如何选择嵌入文档中的项目



如何在mongodb中选择嵌入文档中的所有项目?例如,我如何选择书中的所有项目?

{
 "_id": 67
 "Item_1":
       {
        "books": [
            {"genre": "Classics", "author": "something"},
            {"genre": "Fiction", "author": "something"}
            {"genre": "Fiction", "author": "something"}
         ]¨
       }
}

如果您希望稍微"平坦"一下您的模式,那么您可以使用聚合框架并使用 $project 管道操作符来做到这一点。这比.find()提供的投影有更多的特性,在这个示例中,您还使用 $unwind 将数组"反规范化"为文档:

db.collection.aggregate([
    { "$unwind": "$Item_1.books" },
    { "$project": {
        "genre": "$Item_1.books.genre", "author": "$Item_1.books.author"
    }}
])

结果如下:

{ "_id": 67, "genre": "Classics", "author": "something" },
{ "_id": 67, "genre": "Fiction", "author": "something" }
{ "_id": 67, "genre": "Fiction", "author": "something" }

在那里保留一些引用原始文档的东西是有一定意义的,除非您将其排除在外,否则_id将在那里。但如果你真的想要的话,你也可以排除。

另外,您可以针对多个结果筛选此列表,例如仅获得"小说"类型:

db.collection.aggregate([
    { "$unwind": "$Item_1.books" },
    { "$match": { "Item_1.books.genre": "Fiction" } }
    { "$project": {
        "genre": "$Item_1.books.genre", "author": "$Item_1.books.author"
    }}
])

给你:

{ "_id": 67, "genre": "Fiction", "author": "something" }
{ "_id": 67, "genre": "Fiction", "author": "something" }

对于多个文档,在管道中首先使用额外的 $match 也是有意义的,以减少在其数组中不包含"Fiction"类型的文档的数量。

MongoDB 2.6的另一种形式也可以这样做:

db.collection.aggregate([
    { "$match": { "Item_1.books.genre": "Fiction" } },
    { "$project": {
        "books": {
            "$setDifference: [
                { "$map": {
                    "input ": "$Item_1.books",
                    "as": "el",
                    "in": {
                        "$cond": [
                            { "$eq": [ "$$el.genre", "Fiction" ] },
                            "$$el",
                            false
                        ]
                    }
                }},
                [false]
            ]
        }
    }},
    { "$unwind": "$books" },
    { "$project": {
        "genre": "$books.genre",
        "author": "$books.fiction"
    }}
])

这将数组元素上的 $match 移动到"内联"版本,以使用 $map $setDifference 过滤数组的内容。这只是另一种方法,考虑到数组的大小,它的效用可能会有所不同,其中小的大小没有什么区别。

最后需要注意的是,您的模式似乎与作为对象的"Item_1"键分开了。如果您的实际意图是有许多这样的查询,并且确实在它们之间搜索或组合结果,那么模式更改将大大有利于您的查询:

{
    "_id": 67
    "books": [
        {"type": "Item1", "genre": "Classics", "author": "something"},
        {"type": "Item1", "genre": "Fiction", "author": "something"},
        {"type": "Item1", "genre": "Fiction", "author": "something"},
        {"type": "Item2", "genre": "Fiction", "author": "something"}
    ]¨
}

这样可以很容易地组合不同的键,或者实际上是分开或分组,而不必像现在那样直接指定到字段的路径。

相关内容

  • 没有找到相关文章

最新更新