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

Как да използвате $in или $nin в mongo агрегация $group $cond

Сравнението на $setIsSubset е по-кратка опция от $or условие, което използвате, въпреки че все още е основно валидно да правите това, което правите.

Единствената уловка с $setIsSubset е, че всеки аргумент е масив, така че трябва да конвертирате единичния елемент като масив от единичен елемент. Това е достатъчно лесно с помощта на $map :

db.collectionName.aggregate([
    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$setIsSubset": [
                        { "$map": {
                            "input": ["A"],
                            "as": "el",
                            "in": "$id"
                        }},
                        [ 0,100,101,102,103,104,105 ],
                    ]},
                    1,
                    0
                ]
            }
        }
    }}    
])

Или, ако предпочитате, съпоставете масива от аргументи срещу единствената стойност вместо това с $anyElementTrue :

db.collectionName.aggregate([
    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$anyElementTrue": { "$map": {
                        "input": [ 0,100,101,102,103,104,105 ],
                        "as": "el",
                        "in": { "$eq": [ "$$el", "$id" ] }
                    }}},
                    1,
                    0
                ]
            }
        }
    }}
])

Където е $map е по-скоро обхождане на аргументите за съпоставяне с единственото число, вместо принудително вкарване на единственото в масив.

И разбира се, тъй като и двете форми по същество предоставят true/false към $cond тогава можете просто да обърнете логиката с $not където е необходимо:

db.collectionName.aggregate([
    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$not": [{ "$anyElementTrue": { "$map": {
                        "input": [ 0,100,101,102,103,104,105 ],
                        "as": "el",
                        "in": { "$eq": [ "$$el", "$id" ] }
                    }}}]},
                    1,
                    0
                ]
            }
        }
    }}
])

Наистина зависи от това как го гледате, но просто като предоставени аргументи тогава наистина не печелите нищо спрямо оригиналната форма с $or . Може да изглежда малко по-чисто и „по-лесно за въвеждане“, но обикновено не бих „въвеждал“ такава логика в тръбопровода за агрегиране директно, а по-скоро генерирах тази част от структурата въз основа на обикновен списък на първо място:

т.е.

var failList = [ 0,100,101,102,103,104,105 ];

var orCondition = failList.map(function(el) { 
    return { "$eq": [ "$id", el ] }
})

И след това просто използвайки повторно картографираното съдържание на масива в дефиницията на конвейера:

    { "$group": {
        "_id": "$createdAt",
        "count": { "$sum": 1 },
        "count_failure": {
            "$sum": {
                "$cond": [
                    { "$or": orCondition },
                    1,
                    0
                ]
            }
        }
    }}
])

Откъдето и да го погледнете, не забравяйте, че всичко е просто структури от данни и имате основни процеси за манипулиране. Както вътре в обработката на тръбопровода, така и в самата конструкция на тръбопровода.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. защо не мога да стартирам mongodb

  2. Внедрете функция за автоматично довършване с помощта на търсене в MongoDB

  3. MongoDB:Сортиране по индекс на масив

  4. Как да принудите MongoDB pullAll да пренебрегне реда на документите

  5. Странно поведение на MongoDB LINQ доставчик за полета, наречени id