MongoDB -如何访问文档中的字段



我正在试着做下面的问题。

  1. 查找2022年出版图书的ISBN和书名。

  2. 查找至少有两位作者最多三位作者的图书的ISBN、书名和出版商。

MongoDB subject.js

对于问题1,我试过:我想尝试使用$eq,但我不太确定如何,所以我尝试使用$elemMatch,但似乎我不知道它是如何工作的。

db.Subject.aggregate( [
{"$unwind":"$subject.book"},
{"$match":{"subject.book":{"$elemMatch":{"subject.yearPub":2022}} }},
{"$project":{"subject.book.ISBN":1,"subject.book.bookTitle":1 }}
])

对于问题2,我试过:到目前为止,它给了我三个作者的书。但由于某种原因,它错过了有两个作者的书。

db.Subject.aggregate([{"$match": {"$or": [{'subject.book.author.3': {"$exists": true}},
{'book.author.2': {"$exists": true}}]}},
{"$project": {"subject.book.ISBN": 1,"subject.book.bookTitle": 1,"subject.book.publisher": 1,"_id":0}}
]).pretty()

Q1:带点符号的过滤器:"subject.book.yearPub">

db.Subject.aggregate([
{
"$unwind": "$subject.book"
},
{
"$match": {
"subject.book.yearPub": 2022
}
},
{
"$project": {
"subject.book.ISBN": 1,
"subject.book.bookTitle": 1
}
}
])

Demo Q1 @ Mongo Playground

更新:过滤数组中的文档

db.collection.aggregate([
{
"$match": {
"subject.book.yearPub": 2022
}
},
{
$set: {
"subject.book": {
$filter: {
input: "$subject.book",
cond: {
$eq: [
"$$this.yearPub",
2022
]
}
}
}
}
},
{
"$project": {
"subject.book.ISBN": 1,
"subject.book.bookTitle": 1
}
}
])

演示Q1.1 @ Mongo Playground


Q2:我怀疑你观察结果不正确。subject.book.author.3将返回subject.book.author数组中的第四个元素,索引从0开始。

对于当前的查询,它将返回subject.book.author数组中包含第三和第四个元素的文档,这意味着只要数组包含大于2元素,则返回文档。

相反,您需要$size操作符来获取数组的大小。虽然有些文档没有book属性,所以使用$ifNull来返回空数组,以防止在使用$size时出现错误。
db.Subject.aggregate([
{
"$match": {
$expr: {
$in: [
{
$size: {
$ifNull: [
"$subject.book.author",
[]
]
}
},
[
2,
3
]
]
}
}
},
{
"$project": {
"subject.book.ISBN": 1,
"subject.book.bookTitle": 1,
"subject.book.publisher": 1,
"_id": 0
}
}
])

演示Q2 @ Mongo Playground

更新:过滤数组中的文档

db.collection.aggregate([
{
"$match": {
$expr: {
$in: [
{
$size: {
$ifNull: [
"$subject.book.author",
[]
]
}
},
[
2,
3
]
]
}
}
},
{
$set: {
"subject.book": {
$filter: {
input: "$subject.book",
cond: {
$in: [
{
$size: {
$ifNull: [
"$subject.book.author",
[]
]
}
},
[
2,
3
]
]
}
}
}
}
},
{
"$project": {
"subject.book.ISBN": 1,
"subject.book.bookTitle": 1,
"subject.book.publisher": 1,
"_id": 0
}
}
])

演示Q2.1 @ Mongo Playground


注意:您在一个问题中附加了太多问题。当你在将来问一个新的问题时,请记住把它分成不同的问题(帖子)。

对于问题2,由于Yong Shun提到数组从0开始,因此我编辑了相应的代码。此外,如果您希望将每本书作为单独的记录收集,则需要将它们展开到图书级别。我希望这能回答你的问题。我是MongoDB的新手,所以让我知道如果它不按预期工作。

db.collection.aggregate([
{
"$unwind": "$subject.book"
},
{
"$match": {
"$or": [
{
"subject.book.author.2": {
"$exists": true
}
},
{
"subject.book.author.1": {
"$exists": true
}
}
]
}
},
{
"$project": {
"subject.book.ISBN": 1,
"subject.book.bookTitle": 1,
"subject.book.publisher": 1,
"_id": 0
}
}
])

点击Q2 MongoDB Playground

您也可以使用$filter:

代替$unwind
db.collection.aggregate([
{
$match: {
"subject.book": { $exists: true }
}
},
{
"$project": {
book: {
$filter: {
input: "$subject.book",
cond: { $eq: [ "$$this.yearPub", 2022 ] }
}
}
}
}
])

Mongo操场

最新更新