在子文档中创建多个数组的唯一列表。

时间:2018-05-17 19:03:33

标签: mongodb mongodb-query aggregation-framework

我想在子文档中创建一个唯一的数组值列表。

文件:

  {
    "_id" : ObjectId("5aee0e3c059638093b69c8b3"),
    "firstname" : "John",
    "lastname" : "Doe",
    "websites" : [ 
        {
            "_id" : ObjectId("123"),
            "key" : "website2",
            "url" : "www.xxx.com",
            "tags" : [ 
                "php", 
                "python", 
                "java"
            ]
        },
        {
            "_id" : ObjectId("456"),
            "key" : "website2",
            "url" : "www.yyy.com",
            "tags" : [ 
                "java",
                "php"
            ]
        },
        {
            "_id" : ObjectId("789"),
            "key" : "website3",
            "url" : "www.zzz.com",
            "tags" : [ 
                "java",
                "html",
                "css"
            ]
        }
    ]
}

预期产出:

{
    "_id" : ObjectId("5aee0e3c059638093b69c8b3"),
    "firstname" : "John",
    "lastname" : "Doe",
    "unique_tags": [
        "java",
        "php",
        "python",
        "html",
        "css",
    ],
    "websites" : [ 
        {
            "_id" : ObjectId("123"),
            "key" : "website2",
            "url" : "www.xxx.com",
            "tags" : [ 
                "php", 
                "python", 
                "java"
            ]
        },
        {
            "_id" : ObjectId("456"),
            "key" : "website2",
            "url" : "www.yyy.com",
            "tags" : [ 
                "java",
                "php"
            ]
        },
        {
            "_id" : ObjectId("789"),
            "key" : "website3",
            "url" : "www.zzz.com",
            "tags" : [ 
                "java",
                "html",
                "css"
            ]
        }
    ]
}

看起来Mongo具有distinct功能,但这在aggregate查询中不起作用(对吗?!)。 还尝试在websites.tags上展开并使用addToSet功能,但它也没有正确的输出。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

您可以尝试以下聚合:

db.col.aggregate([
    {
        $addFields: {
            unique_tags: {
                $reduce: {
                    input: { 
                        $concatArrays: {
                            $map: {
                                input: "$websites",
                                as: "website",
                                in: "$$website.tags"
                            }
                        } 
                    },
                    initialValue: [],
                    in: { $setUnion : ["$$value", "$$this"]}
                }
            }
        }
    }
])

要展平数组数组(websites - > tags),您可以将$map$concatArrays一起使用。然后,您将从所有网站获得所有标签的数组。要获得唯一值,您可以将$reduce$setUnion一起使用(删除重复项)。