MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Jak używać $in lub $nin w agregacji mongo $group $cond

Porównanie $setIsSubset jest krótszą opcją niż $lub warunku, którego używasz, chociaż zasadniczo można robić to, co robisz.

Jedyny haczyk z $setIsSubset jest to, że każdy argument jest tablicą, więc musisz przekonwertować pojedynczy element na tablicę pojedynczego elementu. Jest to dość łatwe przy użyciu $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
                ]
            }
        }
    }}    
])

Lub, jeśli wolisz, zamiast tego dopasuj tablicę argumentów do wartości pojedynczej, wpisując $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
                ]
            }
        }
    }}
])

Gdzie $map jest raczej przechodzeniem przez argumenty w celu dopasowania do liczby pojedynczej, a nie zmuszaniem liczby pojedynczej do tablicy.

I oczywiście, ponieważ każda forma zasadniczo dostarcza true/false do $cond wtedy możesz po prostu odwrócić logikę za pomocą $not tam, gdzie jest to wymagane:

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
                ]
            }
        }
    }}
])

To naprawdę zależy od tego, jak na to patrzysz, ale po prostu jako dostarczone argumenty, tak naprawdę nie zyskujesz nic ponad oryginalną formę za pomocą $lub . Może to wyglądać na nieco czystsze i „łatwiejsze do wpisania”, ale zazwyczaj nie „wpisywałbym” takiej logiki bezpośrednio w potoku agregacji, ale raczej generował tę część struktury na podstawie zwykłej listy:

tj.

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

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

A potem wystarczy użyć ponownie zmapowanej zawartości tablicy w definicji potoku:

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

Niezależnie od tego, jak na to spojrzysz, pamiętaj, że to tylko struktury danych i masz podstawowe procesy do manipulacji. Zarówno w procesie przetwarzania rurociągu, jak i w samej konstrukcji rurociągu.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Klaster mongodb z punktem końcowym ELB jako dns

  2. Nie można połączyć się z MongoDB przez PHP

  3. Mongoose zaludnia subdoc

  4. Odwoływanie się do innego schematu w Mongoose

  5. MongoDB:jak utworzyć uwierzytelnioną bazę danych za pomocą sterownika java