34

我有一个集合 Notebook,其中嵌入了名为 Notes 的数组文档。样本

文件如下所示。

{
"_id" : ObjectId("4f7ee46e08403d063ab0b4f9"),
"name" : "MongoDB",
"notes" : [
            {
              "title" : "Hello MongoDB",
              "content" : "Hello MongoDB"
            },
            {
              "title" : "ReplicaSet MongoDB",
              "content" : "ReplicaSet MongoDB"
            }
         ]
}

我只想找出标题为“Hello MongoDB”的注释。我没有得到应有的东西

成为查询。谁能帮我。

4

5 回答 5

88

您可以使用更高版本 2.2 的 mongo 执行此操作

像这样的查询:

db.coll.find({ 'notes.title': 'Hello MongoDB' }, {'notes.$': 1});

$elemMatch你可以像贾斯汀詹金斯一样尝试

于 2013-07-12T10:37:55.490 回答
39

过时的答案:请参阅其他答案。


我不相信你的要求是可能的,至少没有一些 map-reduce 可能?

请参阅此处:过滤 MongoDB 中的嵌入文档

该答案建议您更改架构,以更好地适应您希望使用数据的方式。

您可以使用“点表示法”或 $elemMatch 来取回具有匹配“注释标题”的正确文档...

> db.collection.find({ "notes.title" : "Hello MongoDB"}, { "notes.title" : 1"});

或者 ...

> db.collection.find({ "notes" : { "$elemMatch" : { "title" : "Hello MongoDB"} }});

但是您将取回整个数组,而不仅仅是导致匹配的数组元素。

另外,需要考虑的事情......使用您当前的设置,很难对数组中的项目进行任何操作。

如果您不更改架构(如链接到的答案所示)......我会考虑将“ids”添加到数组中的每个元素,以便您可以在需要时轻松删除它。

于 2012-04-06T18:19:39.950 回答
8

您可以在 MongoDb 版本 3.2+ 中使用聚合来执行此操作。

询问:

db.Notebook.aggregate(
    {
        $project: {
            "notes": {
                $filter: {
                    input: "$notes",
                    as: "note",
                    cond: { 
                        $eq: [ "$$note.title", "Hello MongoDB" ]
                    }
                }
            }
        }
    }
)

结果:

{ 
    "_id" : ObjectId("4f7ee46e08403d063ab0b4f9"), 
    "notes" : [ 
        { 
            "title" : "Hello MongoDB", 
            "content" : "Hello MongoDB" 
        } 
    ] 
}

$$在这里用来访问变量。note我在这里用来访问$filter.

您可以在官方文档中找到有关$filter$eq$$的更多详细信息。

$filter:根据指定条件选择要返回的数组子集。返回一个仅包含符合条件的元素的数组。返回的元素按原始顺序排列。

$eq:比较两个值并在值相等或不相等时返回 true/false (...)。

$$:变量可以保存任何 BSON 类型的数据。要访问变量的值,请使用带有双美元符号 ($$) 前缀的变量名称的字符串。


笔记:

贾斯汀詹金的答案已经过时,kop 的答案在这里没有从集合中返回多个文档。使用此聚合查询,您可以在需要时返回多个文档。

我需要这个并想发布以帮助某人。

于 2017-08-21T16:46:12.923 回答
0

您可以使用 $ 或 $elemMatch。$ 运算符和 $elemMatch 运算符根据条件从数组中投影元素的子集。

$elemMatch 投影运算符采用显式条件参数。这使您可以根据不在查询中的条件进行投影。

db.collection.find(
    {
        // <expression>
    },
    {
        notes: {
            $elemMatch: {
                title: 'Hello MongoDB'
            }
        },
        name: 1
    }
)

$ 运算符根据查询语句中的某些条件投影数组元素。

db.collection.find(
    {
        'notes.title': 'Hello MongoDB'
    },
    {
        'notes.title.$': 1,
         name: 1
    }
)
于 2017-04-12T12:36:11.173 回答
-3

您可以像这样执行查询:

db.coll.find({ 'notes.title': 'Hello MongoDB' });

您还可以参考文档以获取更多详细信息。

于 2012-04-06T17:33:16.580 回答