db.aaa.insert({"_id":1, "m":[{"_id":1,"a":1},{"_id":2,"a":2}]})
db.aaa.find({"_id":1,"m":{$elemMatch:{"_id":1}}})
{ "_id" : 1, "m" : [ { "_id" : 1, "a" : 1 }, { "_id" : 2, "a" : 2 } ] }
使用$ elemMatch作为查询运算符,它返回'm'中的所有子文档!!奇怪!
将其用作项目运营商:
db.aaa.find({"_id":1},{"m":{$elemMatch:{"_id":1}}})
{ "_id" : 1, "m" : [ { "_id" : 1, "a" : 1 } ] }
这没关系。遵循此逻辑,将其用作更新中的查询运算符将更改“m”中的所有子文档。所以我这样做:
db.aaa.update({"_id":1,"m":{$elemMatch:{"_id":1}}},{$set:{"m.$.a":3}})
db.aaa.find()
{ "_id" : 1, "m" : [ { "_id" : 1, "a" : 3 }, { "_id" : 2, "a" : 2 } ] }
它以第二个例子(项目操作员)的方式工作。这真让我迷惑。 给我一个解释
答案 0 :(得分:1)
这并不奇怪,它是如何运作的。
您正在使用$ elemMatch 匹配文档中包含的数组中的元素。这意味着 mactches “文档”而不是“数组元素”,因此它不仅仅选择性地显示匹配的数组元素。
你可以做什么,以及如何在$ set运算符中使用它,使用位置$运算符来指示查询端匹配的“位置”:
db.aaa.find({"_id":1},{"m":{$elemMatch:{"_id":1}}},{ "m.$": 1 })
这将只显示数组的一个元素。但它当然是* 仍然显示的结果中的数组,并且您无法将其转换为其他类型。
另一部分用法是仅匹配一次。并且只有第一个匹配将分配给位置运算符。
因此,或许最简洁的解释是您匹配“包含”您查询中指定的子文档属性的文档,以及不仅“子文档”本身。< / p>
有关更多信息,请参阅文档:
http://docs.mongodb.org/manual/reference/operator/projection/positional/ http://docs.mongodb.org/manual/reference/operator/query/elemMatch/