MongoDB - 在结果集中过滤内部数组的内容
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4701427/
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
MongoDB - Filtering the content of an internal Array in a resultset
提问by Martin Zugnoni
I'm new using MongoDB, and I don't know how to solve the next problem:
我是MongoDB新手,不知道如何解决下一个问题:
I have a collection of documents like this:
我有一组这样的文件:
{
"URL": "www.stackoverflow.com",
"TAGS": [
{"NAME": "question", "VOTES": 3},
{"NAME": "answer", "VOTES": 5},
{"NAME": "problem", "VOTES": 2}
]
}
First of all, I wanted all the Urls that have all the tags given in a list. I have solved this by quering:
首先,我想要所有具有列表中给出的所有标签的 URL。我通过查询解决了这个问题:
db.links.find( { "Tags.Name" : { $all: ["question","answers"] } } );
But this query return the whole correct document, insted of only the correct document with only the tags I have asked for.
但是这个查询返回整个正确的文档,只包含正确的文档,只有我要求的标签。
The result I'm looking for is:
我正在寻找的结果是:
{
"URL": "www.stackoverflow.com",
"TAGS": [{"NAME": "question", "VOTES": 3},
{"NAME": "answer", "VOTES": 5}]
}
and not:
并不是:
{
"URL": "www.stackoverflow.com",
"TAGS": [{"NAME": "question", "VOTES": 3},
{"NAME": "answer", "VOTES": 5},
{"NAME": "problem", "VOTES": 2}]
}
Because I've only asked for the tags ["question","answers"].
因为我只要求标签 ["question","answers"]。
I thought about using MapReduce or parsing the resultset, but I don't know if it is the correct way of solving the problem. Maybe there is a builtin function that solve it more efficiently.
想过使用MapReduce或者解析resultset,不知道是不是解决问题的正确方法。也许有一个内置函数可以更有效地解决它。
Thanks!
谢谢!
采纳答案by Martin Zugnoni
回答by Ahmet DAL
You can use aggregation framework of MongoDB
.
您可以使用MongoDB
.
If you have a doc in your collection like ;
如果您的收藏中有一个文档,例如;
{
"URL": "www.stackoverflow.com",
"TAGS": [
{"NAME": "question", "VOTES": 3},
{"NAME": "answer", "VOTES": 5},
{"NAME": "problem", "VOTES": 2}
]
}
and you want to filter some elements of the array out you can use the aggregation sample;
并且您想过滤掉数组的某些元素,您可以使用聚合示例;
db.sof_table.aggregate
([
{$unwind:'$TAGS'},
{$match:{'TAGS.NAME':{$in:['answer','question']}}},
{$group:{_id:'$URL',TAGS:{$push:'$TAGS'}}}
])
This will result;
这将导致;
{
"result" : [
{
"_id" : "www.stackoverflow.com",
"TAGS" : [
{
"NAME" : "question",
"VOTES" : 3
},
{
"NAME" : "answer",
"VOTES" : 5
}
]
}
],
"ok" : 1
}
as your expected result.
作为您的预期结果。
回答by RobV
Generally speaking any find()
operation on MongoDB returns all the documents that match the query and all documents are retrieved in their entirety. If you only want a specific section of a document then you have to do that processing on the client side.
一般来说find()
,MongoDB上的任何操作都会返回与查询匹配的所有文档,并且所有文档都被完整检索。如果您只想要文档的特定部分,那么您必须在客户端进行该处理。
This is a fundamental difference between document databases and SQL databases. Typically in a document database a query returns all documents that match it while in an SQL database you can choose to return only portions of the table. Unless of course like you say you do a MapReduce but that kinda seems like overkill for your use case.
这是文档数据库和 SQL 数据库之间的根本区别。通常,在文档数据库中,查询会返回与其匹配的所有文档,而在 SQL 数据库中,您可以选择仅返回表的一部分。当然,除非你说你做了一个 MapReduce,但这对你的用例来说似乎有点矫枉过正。
Not to discourage you from using MongoDB but whatever project you work on consider whether NoSQL databases actually fit the bill (do they fill a requirement that SQL cannot) or whether you'd still be better going with a traditional SQL database.
并不是要阻止您使用 MongoDB,但无论您从事什么项目,都要考虑 NoSQL 数据库是否真正符合要求(它们是否满足 SQL 不能满足的要求),或者您是否仍然最好使用传统的 SQL 数据库。
回答by Robert Stewart
It is possible to suppress keys and array elements in the returned document, but not in the way that you want.
可以抑制返回文档中的键和数组元素,但不是您想要的方式。
In your example, you can suppress the URL key with the following query, which uses the second argument to find():
在您的示例中,您可以使用以下查询取消 URL 键,该查询使用 find() 的第二个参数:
db.links.find({"TAGS.NAME" : {$all : ["question","answer"]}}, {"URL" : 0})
However, I don't believe it is possible to suppress individual members of an array on the server-side with find() based on which array members were specified with $all.
但是,我认为不可能根据 $all 指定的数组成员使用 find() 在服务器端抑制数组的单个成员。
You can use $slice to return only certain members of an array, but it is position-based. For example,
您可以使用 $slice 仅返回数组的某些成员,但它是基于位置的。例如,
{$slice : [1, 2]}
skips the first element of the array and returns up to the next two.
跳过数组的第一个元素并返回到接下来的两个元素。
回答by Mano Haran
This might help you.
这可能对你有帮助。
The $elemMatch projection operator takes an explicit condition argument. This allows you to project based on a condition not in the query, or if you need to project based on multiple fields in the array's embedded documents.**
$elemMatch 投影运算符采用显式条件参数。这允许您根据不在查询中的条件进行投影,或者如果您需要根据数组嵌入文档中的多个字段进行投影。**
https://docs.mongodb.com/manual/reference/operator/projection/elemMatch/
https://docs.mongodb.com/manual/reference/operator/projection/elemMatch/