mongodb 如何在聚合投影上使用 $elemMatch?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25528217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use $elemMatch on aggregate's projection?
提问by Stephen Lynx
This is my object:
这是我的对象:
{ "_id" : ObjectId("53fdcb6796cb9b9aa86f05b9"), "list" : [ "a", "b" ], "complist" : [ { "a" : "a", "b" : "b" }, { "a" : "c", "b" : "d" } ] }
And this is what I want to accomplish: check if "list" contains a certain element and get only the field "a" from the objects on "complist" while reading the document regardless of any of these values. I'm building a forum system, this is the query that will return the details of a forum. I need to read the forum information while knowing if the user is in the forum's white list.
这就是我想要完成的:检查“list”是否包含某个元素,并在阅读文档时只从“complist”上的对象中获取字段“a”,而不管这些值中的任何一个。我正在构建一个论坛系统,这是将返回论坛详细信息的查询。我需要阅读论坛信息,同时知道用户是否在论坛的白名单中。
With a find I can use the query
通过查找,我可以使用查询
db.itens.find({},{list:{$elemMatch:{$in:["a"]}}})
to get only the first element that matches a certain value. This way I can just check if the returned array is not empty and I know if "list" contains the value I'm looking for. I can't do it on the query because I want the document regardless of it containing the value I'm looking for in the "list" value. I need the document AND know if "list" has a certain value.
只获取匹配某个值的第一个元素。这样我就可以检查返回的数组是否为空,并且我知道“列表”是否包含我正在寻找的值。我无法在查询中执行此操作,因为我想要该文档,而不管它是否包含我在“列表”值中查找的值。我需要文档并知道“列表”是否具有特定值。
With an aggregate I can use the query
使用聚合,我可以使用查询
db.itens.aggregate({$project:{"complist.a":1}})
to read only the field "a" of the objects contained in complist. This is going to get the forum's threads basic information, I don't want all the information of the threads, just a couple of things.
仅读取 complist 中包含的对象的字段“a”。这将获得论坛线程的基本信息,我不想要线程的所有信息,只需要一些东西。
But when I try to use the query
但是当我尝试使用查询时
db.itens.aggregate({$project:{"complist.b":1,list:{$elemMatch:{$in:["a"]}}}})
to try and do both, it throws me an error saying the operator $elemMatch is not valid.
要尝试同时执行这两项操作,它会向我抛出一个错误,指出运算符 $elemMatch 无效。
Am I doing something wrong here with the $elemMatch in aggregate? Is there a better way to accomplish this?
我在这里用 $elemMatch 做错了什么吗?有没有更好的方法来实现这一点?
采纳答案by Stephen Lynx
Well, it happens you can use "array.field" on a find's projection block.
好吧,碰巧您可以在查找的投影块上使用“array.field”。
db.itens.find({},{"complist.b":1,list:{$elemMatch:{$in:["a"]}}})
did what I needed.
做了我需要的。
回答by Graeme Pyle
For some reason $elemMatch doesn't work in aggregations. You need to use the new $filter operator in Mongo 3.2. See https://docs.mongodb.org/manual/reference/operator/aggregation/filter/
出于某种原因, $elemMatch 在聚合中不起作用。您需要在 Mongo 3.2 中使用新的 $filter 运算符。请参阅https://docs.mongodb.org/manual/reference/operator/aggregation/filter/
回答by Graeme Pyle
Actually, the simplest solution is to just $unwind your array, then $match the appropriate documents. You can wind-up the appropriate documents again using $group and $push.
实际上,最简单的解决方案是 $unwind 您的数组,然后 $match 相应的文档。您可以使用 $group 和 $push 再次结束适当的文档。
回答by Hevelson Rosario
The answer to this questionmaybe help.
这个问题的答案可能会有所帮助。
db.collection_name.aggregate({
"$match": {
"complist": {
"$elemMatch": {
"a": "a"
}
}
}
});
回答by Paulo Pedroso
Although the question is old, here is my contribution for November 2017.
虽然这个问题很老,但这是我 2017 年 11 月的贡献。
I had similar problem and doing two consecutive match operations worked for me. The code below is a subset of my whole code and I changed elements names, so it's not tested. Anyway this should point you in the right direction.
我有类似的问题,连续两次匹配操作对我有用。下面的代码是我整个代码的一个子集,我更改了元素名称,因此没有经过测试。无论如何,这应该为您指明正确的方向。
db.collection.aggregate([
{
"$match": {
"_id": "ID1"
}
},
{
"$unwind": "$sub_collection"
},
{
"$match": {
"sub_collection.field_I_want_to_match": "value"
}
}
])