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

MongoDB:Преброяване колко елементи с дадена стойност съществуват в масив, който е в документ?

Рамката за агрегиране е идеална за такива. Помислете за изпълнение на следния конвейер, за да получите желания резултат.

pipeline = [
    {
        "$match": {
            "name": "james",
            "books.year": 1990
        }
    },
    {
        "$project": {
            "numberOfBooks": {
                "$size": {                  
                    "$filter": {
                        "input": "$books",
                        "as": "el",
                        "cond": { "$eq": [ "$$el.year", 1990 ] }
                    }                   
                }
            }
        }
    }
];
db.collection.pipeline(pipeline);

Горният канал използва новия $filter оператор, наличен за MongoDB 3.2, за да създаде масив, който отговаря на определеното условие, т.е. филтрира външни елементи, които не отговарят на критериите. Първоначалният $match тръбопроводът е необходим за филтриране на документи, които попадат в тръбопровода за агрегиране на ранен етап като стратегия за оптимизиране на конвейера.

$size оператор, който приема един израз като аргумент, след което ви дава броя на елементите в резултантния масив, като по този начин имате желания брой книги.

За алтернативно решение, което не използва $ филтър оператор, който не е намерен в по-ранни версии, разгледайте следната конвейерна операция:

pipeline = [
    {
        "$match": {
            "name": "james",
            "books.year": 1990
        }
    },
    {
        "$project": {
            "numberOfBooks": {
                "$size": {                  
                    "$setDifference": [
                        {
                            "$map": {
                                "input": "$books",
                                "as": "el",
                                "in": {
                                    "$cond": [
                                        { "$eq": [ "$$el.year", 1990 ] },
                                        "$$el",
                                        false
                                    ]
                                }
                            }
                        },
                        [false]
                    ]                   
                }
            }
        }
    }
];
db.collection.pipeline(pipeline);

$project етапът на тръбопровод включва монтиране на масива от книги, така че да премахнете документите, които нямат годината 1990. Това е възможно чрез $setDifference и $map оператори.

$map операторът по същество създава ново поле за масив, което съдържа стойности в резултат на изчислената логика в подизраз към всеки елемент от масив. $setDifference след това операторът връща набор с елементи, които се появяват в първия набор, но не и във втория набор; т.е. извършва относително допълнение на втория набор спрямо първия. В този случай той ще върне окончателния масив от книги, който има елементи с година 1990 и впоследствие $size изчислява броя на елементите в резултантния масив, като по този начин ви дава броя на книгите.

За решение, което използва $unwind оператор, като се има предвид, че (благодарение на този проницателен отговор от @BlakesSeven в коментарите):

и в краен случай изпълнете следния конвейер:

pipeline = [
    {
        "$match": {
            "name": "james",
            "books.year": 1990
        }
    },
    { "$unwind": "$books" },
    {
        "$match": { "books.year": 1990 }
    },
    {
        "$group": {
            "_id": null
            "count": { "$sum": 1 }
        }
    }
]
db.collection.pipeline(pipeline)


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. MongoDB - актуализирайте поддокумент с $set

  2. Как да пишем заявки за съюз в mongoDB

  3. Как да прехвърлите екземпляр на Google Compute Engine?

  4. MongoDB oplog има записи с точки в имената на ключовете, които не могат да бъдат търсени, afaict

  5. Meteor - collection.find() винаги връща всички полета