MongoDB:查找具有给定子文档数组的文档
MongoDB: find documents with a given array of subdocuments
我想查找包含给定子文档的文档,假设我的 commits
集合中有以下文档:
// Document 1
{
"commit": 1,
"authors" : [
{"name" : "Joe", "lastname" : "Doe"},
{"name" : "Joe", "lastname" : "Doe"}
]
}
// Document 2
{
"commit": 2,
"authors" : [
{"name" : "Joe", "lastname" : "Doe"},
{"name" : "John", "lastname" : "Smith"}
]
}
// Document 3
{
"commit": 3,
"authors" : [
{"name" : "Joe", "lastname" : "Doe"}
]
}
我想要从上面的集合中得到第一个文件,因为我知道我正在寻找一个 commit
和 2 authors
都具有相同的 name
和 lastname
.所以我提出了查询:
db.commits.find({
$and: [{'authors': {$elemMatch: {'name': 'Joe,
'lastname': 'Doe'}},
{'authors': {$elemMatch: {'name': 'Joe,
'lastname': 'Doe'}}],
'authors': { $size: 2 }
})
$size
用于过滤掉第 3 个文档,但查询仍然是 return 的第 2 个文档,因为 $elemMatch
return 都为真。
我不能对子文档使用索引,因为用于搜索的作者顺序是随机的。有没有办法在不使用 Mongo 的聚合函数的情况下从结果中删除第二个文档?
您在这里查询的内容与标准查询略有不同。事实上,您是在询问 "name" 和 "lastname" 在数组中的那个组合中的位置 两次 次或更多次以识别该文档。
标准查询参数不匹配 "how many times"结果中匹配了一个数组元素。但是你当然可以使用 aggregation framework:
请求服务器 "count"
db.collection.aggregate([
// Match possible documents to reduce the pipeline
{ "$match": {
"authors": { "$elemMatch": { "name": "Joe", "lastname": "Doe" } }
}},
// Unwind the array elements for processing
{ "$unwind": "$authors" },
// Group back and "count" the matching elements
{ "$group": {
"_id": "$_id",
"commit": { "$first": "$commit" },
"authors": { "$push": "$authors" },
"count": { "$sum": {
"$cond": [
{ "$and": [
{ "$eq": [ "$authors.name", "Joe" ] },
{ "$eq": [ "$authors.lastname", "Doe" ] }
]},
1,
0
]
}}
}},
// Filter out anything that didn't match at least twice
{ "$match": { "count": { "$gte": 2 } } }
])
所以基本上你只是在 $cond
operator which returns 1
where matched and 0
where not, and this is passed to $sum
中匹配你的条件以获得文档的总数。
然后过滤掉任何不匹配 2 次或更多次的文档
我想查找包含给定子文档的文档,假设我的 commits
集合中有以下文档:
// Document 1
{
"commit": 1,
"authors" : [
{"name" : "Joe", "lastname" : "Doe"},
{"name" : "Joe", "lastname" : "Doe"}
]
}
// Document 2
{
"commit": 2,
"authors" : [
{"name" : "Joe", "lastname" : "Doe"},
{"name" : "John", "lastname" : "Smith"}
]
}
// Document 3
{
"commit": 3,
"authors" : [
{"name" : "Joe", "lastname" : "Doe"}
]
}
我想要从上面的集合中得到第一个文件,因为我知道我正在寻找一个 commit
和 2 authors
都具有相同的 name
和 lastname
.所以我提出了查询:
db.commits.find({
$and: [{'authors': {$elemMatch: {'name': 'Joe,
'lastname': 'Doe'}},
{'authors': {$elemMatch: {'name': 'Joe,
'lastname': 'Doe'}}],
'authors': { $size: 2 }
})
$size
用于过滤掉第 3 个文档,但查询仍然是 return 的第 2 个文档,因为 $elemMatch
return 都为真。
我不能对子文档使用索引,因为用于搜索的作者顺序是随机的。有没有办法在不使用 Mongo 的聚合函数的情况下从结果中删除第二个文档?
您在这里查询的内容与标准查询略有不同。事实上,您是在询问 "name" 和 "lastname" 在数组中的那个组合中的位置 两次 次或更多次以识别该文档。
标准查询参数不匹配 "how many times"结果中匹配了一个数组元素。但是你当然可以使用 aggregation framework:
请求服务器 "count"db.collection.aggregate([
// Match possible documents to reduce the pipeline
{ "$match": {
"authors": { "$elemMatch": { "name": "Joe", "lastname": "Doe" } }
}},
// Unwind the array elements for processing
{ "$unwind": "$authors" },
// Group back and "count" the matching elements
{ "$group": {
"_id": "$_id",
"commit": { "$first": "$commit" },
"authors": { "$push": "$authors" },
"count": { "$sum": {
"$cond": [
{ "$and": [
{ "$eq": [ "$authors.name", "Joe" ] },
{ "$eq": [ "$authors.lastname", "Doe" ] }
]},
1,
0
]
}}
}},
// Filter out anything that didn't match at least twice
{ "$match": { "count": { "$gte": 2 } } }
])
所以基本上你只是在 $cond
operator which returns 1
where matched and 0
where not, and this is passed to $sum
中匹配你的条件以获得文档的总数。
然后过滤掉任何不匹配 2 次或更多次的文档