如何在 MongoDB 集合中获取特定的嵌入文档?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10043965/
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 get a specific embedded document inside a MongoDB collection?
提问by Shekhar
I have a collection Notebook which has embedded array document called Notes. The sample
我有一个集合 Notebook,其中嵌入了名为 Notes 的数组文档。样品
document looks like as shown below.
文档如下所示。
{
"_id" : ObjectId("4f7ee46e08403d063ab0b4f9"),
"name" : "MongoDB",
"notes" : [
{
"title" : "Hello MongoDB",
"content" : "Hello MongoDB"
},
{
"title" : "ReplicaSet MongoDB",
"content" : "ReplicaSet MongoDB"
}
]
}
I want to find out only note which has title "Hello MongoDB". I am not getting what should
我只想找出标题为“Hello MongoDB”的笔记。我没有得到什么应该
be the query. Can anyone help me.
成为查询。谁能帮我。
回答by kop
You can do this with mongo version higher 2.2
您可以使用更高版本的 mongo 2.2 执行此操作
the query like this:
像这样的查询:
db.coll.find({ 'notes.title': 'Hello MongoDB' }, {'notes.$': 1});
you can try with $elemMatch
like Justin Jenkins
你可以$elemMatch
像贾斯汀詹金斯一样尝试
回答by Justin Jenkins
Outdated answer: See the other answers.
过时的答案:请参阅其他答案。
I don't believe what you are asking is possible, at least without some map-reduce maybe?
我不相信您要问的是可能的,至少可能没有一些 map-reduce?
See here: Filtering embedded documents in MongoDB
请参阅此处:在 MongoDB 中过滤嵌入的文档
That answer suggests you change your schema, to better suit how you'd like to work with the data.
该答案建议您更改架构,以更好地适应您希望如何处理数据。
You can use a either "dot notation" or $elemMatch to get back the correct, document that has the matching "note title" ...
您可以使用“点符号”或 $elemMatch 来取回具有匹配“注释标题”的正确文档......
> db.collection.find({ "notes.title" : "Hello MongoDB"}, { "notes.title" : 1"});
or ...
或者 ...
> db.collection.find({ "notes" : { "$elemMatch" : { "title" : "Hello MongoDB"} }});
But you will get back the whole array, not just the array element that caused the match.
但是您将取回整个数组,而不仅仅是导致匹配的数组元素。
Also, something to think about ... with your current setup it woud be hard to do any operations on the items in the array.
另外,需要考虑的事情......使用您当前的设置,很难对数组中的项目进行任何操作。
If you don't change your schema (as the answer linked to suggests) ... I would consider adding "ids" to each element in the array so you can do things like delete it easily if needed.
如果您不更改架构(如链接到的答案所建议的那样)......我会考虑为数组中的每个元素添加“id”,这样您就可以在需要时轻松地删除它。
回答by Inanc Gumus
You can do this in MongoDb version 3.2+ with aggregation.
您可以使用聚合在 MongoDb 3.2+ 版中执行此操作。
Query:
询问:
db.Notebook.aggregate(
{
$project: {
"notes": {
$filter: {
input: "$notes",
as: "note",
cond: {
$eq: [ "$$note.title", "Hello MongoDB" ]
}
}
}
}
}
)
Result:
结果:
{
"_id" : ObjectId("4f7ee46e08403d063ab0b4f9"),
"notes" : [
{
"title" : "Hello MongoDB",
"content" : "Hello MongoDB"
}
]
}
$$used here to access the variable. I used here to access the newly created note
variable inside the $filter
.
$$在这里用来访问变量。我这里使用的访问新创建的note
内部变量$filter
。
You can find additional details in the official documentation about $filter, $eqand $$.
您可以在有关$filter、$eq和$$的官方文档中找到更多详细信息。
$filter:Selects a subset of an array to return based on the specified condition. Returns an array with only those elements that match the condition. The returned elements are in the original order.
$eq:Compares two values and returns true/false when the values are equivalent or not (...).
$$:Variables can hold any BSON type data. To access the value of the variable, use a string with the variable name prefixed with double dollar signs ($$).
$filter:根据指定条件选择要返回的数组子集。返回一个仅包含与条件匹配的元素的数组。返回的元素按原始顺序排列。
$eq:比较两个值并在值相等或不相等时返回真/假(...)。
$$:变量可以保存任何 BSON 类型的数据。要访问变量的值,请使用变量名以双美元符号 ($$) 为前缀的字符串。
Note:
笔记:
Justin Jenkin's answer is outdated and kop's answer here doesn't return multiple documents from the collection. With this aggregation query, you can return multiple documents if needed.
贾斯汀詹金的回答已经过时,kop 的回答没有从集合中返回多个文档。使用此聚合查询,您可以根据需要返回多个文档。
I needed this and wanted to post to help someone.
我需要这个,想发帖帮助别人。
回答by Omar Makled
You can use $ or $elemMatch. The $ operator and the $elemMatch operator project a subset of elements from an array based on a condition.
您可以使用 $ 或 $elemMatch。$ 运算符和 $elemMatch 运算符根据条件从数组中投影元素的子集。
The $elemMatch projection operator takes an explicit condition argument. This allows you to project based on a condition not in the query.
$elemMatch 投影运算符采用显式条件参数。这允许您根据不在查询中的条件进行投影。
db.collection.find(
{
// <expression>
},
{
notes: {
$elemMatch: {
title: 'Hello MongoDB'
}
},
name: 1
}
)
The $ operator projects the array elements based on some condition from the query statement.
$ 运算符根据查询语句中的某些条件来投影数组元素。
db.collection.find(
{
'notes.title': 'Hello MongoDB'
},
{
'notes.title.$': 1,
name: 1
}
)