Создайте уникальный список из нескольких массивов внутри вложенного документа. - PullRequest
0 голосов
/ 17 мая 2018

Я хотел бы создать уникальный список значений массива внутри вложенного документа.

Документ:

  {
    "_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 голосов
/ 17 мая 2018

Вы можете попробовать ниже агрегации:

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 . Тогда вы получите массив всех тегов со всех сайтов. Чтобы получить только уникальные значения, вы можете использовать $ lower с $ setUnion (который удаляет дубликаты).

...