我正在尝试获取符合我条件的子文档。
我的MongoDB查询:
db.SCSIssue.find(
{ _id: ObjectId("5439a2992ea8cc0f70feef2d") },
{ Statuses: { $elemMatch: { StatusID: { $gte : NumberLong(521055087020736513) } } } }
)
我的架构是这样的:
{
....
"_id": ObjectId("5439a2992ea8cc0f70feef2d"),
....
"Statuses": [{
....
"StatusID": NumberLong(525623822633172993),
},{
....
"StatusID": NumberLong(521055087020736513),
},{
....
"StatusID": NumberLong(521060802959532033),
}]
....
},
{
....
"_id": ObjectId("543c04662ea8cd11ec4dda5f"),
....
"Statuses": [{
....
"StatusID": NumberLong(535623822633172993),
},{
....
"StatusID": NumberLong(541055087020736513),
},{
....
"StatusID": NumberLong(551060802959532033),
}]
....
},
....
查询结果:
{
"_id" : ObjectId("5439a2992ea8cc0f70feef2d"),
"Statuses" : [{
....
"StatusID": NumberLong(525623822633172993),
....
}]
}
预期结果:
{
"_id" : ObjectId("5439a2992ea8cc0f70feef2d"),
"Statuses" : [{
....
"StatusID": NumberLong(521055087020736513),
},{
....
"StatusID": NumberLong(521060802959532033),
}]
}
简单地说,我想得到数组(状态)中的子文档大于或等于我的条件和同一时间_id等于我的条件。我已经阅读了很多关于此的答案。所有这些都像我的问题,但在我的情况下,它不是预期的工作。
我错过了什么? 谢谢。
答案 0 :(得分:0)
$elemMatch
的行为没有任何问题。它按预期工作。该文件还说:
但是,$ elemMatch投影仅返回第一个匹配项 数组中的元素。
根据经验,只要您使用array
投射$elemMatch
,只会投射一个元素最多。如果数组中的所有元素都不匹配,则根本不会投影该字段。
因此,您获得的结果是正确的,只有数组中与$elemMatch
中的条件匹配的第一项才是projected
。
{
"_id" : ObjectId("5439a2992ea8cc0f70feef2d"),
"Statuses" : [{
....
"StatusID": NumberLong(525623822633172993),
....
}]
}
您可以尝试更改状态数组中的文档顺序,如果该文档显示在数组中其他匹配文档的前面,则可能会获得不同的匹配文档。
参考:$elemMatch
根据您的要求,如果您想要结果中的所有匹配数组元素,则需要执行聚合操作。
Match
具有所需_id和那些文档的文档
其中包含我们正在搜索的状态子文档。unwind
状态数组。match
个别未展开的文件。group
匹配的文件_id
。守则:
db.collection.aggregate([
{$match:{ "_id": ObjectId("5439a2992ea8cc0f70feef2d"),
"Statuses.StatusID":{$gte : NumberLong(525623822633172993)}}},
{$unwind:"$Statuses"},
{$match:{"Statuses.StatusID":{$gte : NumberLong(525623822633172993)}}},
{$group:{"_id":"$_id",statuses:{$push:"$Statuses"}}}
])
将为您提供数组中所有匹配的子文档。