MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

Как да групирате вложени публикации с рамка за агрегиране на MongoDB?

Следният конвейер трябва да работи за вас:

var pipeline = [
    {
        "$project": {
            "title": 1, "body": 1, 
            "post_id": { "$ifNull": [ "$_post", "$_id" ] }
        }
    },  
    {
        "$group": {
            "_id": "$post_id",
            "title": { "$first": "$title" },
            "body": { "$first": "$body" },
            "comments": {
                "$push": {
                    "_id": "$_id",
                    "_post": "$post_id",
                    "body": "$body"
                }
            }
        }
    },
    {
        "$project": {
            "title": 1, "body": 1,
            "comments": {
                "$setDifference": [
                    {
                        "$map": {
                            "input": "$comments",
                            "as": "el",
                            "in": {
                                "$cond": [
                                    { "$ne": [ "$$el._id", "$$el._post" ] },
                                    "$$el",
                                    false
                                ]
                            }
                        }
                    },
                    [false]
                ]
            }
        }
    }
];

Post.aggregate(pipeline, function (err, result) {
    if (err) { /* handle error */ };
    console.log(result);
});

Тръбопроводът е структуриран по такъв начин, че първата ви стъпка, $project оператор етап, е да се проектира полето post_id да се използва като група по ключ в следващия етап на конвейера. Тъй като вашата схема е йерархична, ще ви е необходимо това поле за родителски/главни документи. $ifNull ще действа като оператор за обединяване и ще върне заместващата стойност, ако полето не съществува в документите.

Следващата стъпка на конвейера, $група етапът на тръбопровод се опитва да групира данните, за да ги обработи. $group конвейерният оператор е подобен на клаузата GROUP BY на SQL. В SQL не можем да използваме GROUP BY, освен ако не използваме някоя от функциите за агрегиране. По същия начин трябва да използваме функция за агрегиране и в MongoDB. В този случай имате нужда от $push оператор за създаване на масива с коментари. След това другите полета се натрупват с помощта на $first оператор.

Последната стъпка включва филтриране на масива с коментари, така че да премахнете документа с подробности за публикацията, който определено не е от тип коментар. Това става възможно чрез $setDifference и $map оператори. $map операторът по същество създава ново поле за масив, което съдържа стойности в резултат на изчислената логика в подизраз към всеки елемент от масив. $setDifference след това операторът връща набор с елементи, които се появяват в първия набор, но не и във втория набор; т.е. извършва относително допълнение на втория набор спрямо първия. В този случай той ще върне окончателните коментари масив, който има елементи, които не са свързани с родителските документи чрез _id собственост.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Вмъкване на текущата дата и час в mongodb

  2. грешка при изчакване на връзката с mongodb

  3. MongoDB заявка за всички шардирани колекции без shardkey

  4. MongoDB множество мастери в ReplicaSet

  5. Има ли добри приложения за управление на бази данни за Mac за MongoDB? Подобно на Sequel Pro?