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

Условие за съвпадение на членовете на масива за обобщен брой

Грешката е, защото вече не е масив, след като $unwind и следователно вече не е валиден аргумент за $size .

Изглежда се опитвате да „слеете“ няколко съществуващи отговора, без да разбирате какво правят. Това, което наистина искате тук, е $filter и $size

db.collection.aggregate([
  { "$project": {
    "total": {
      "$size": {
        "$filter": {
          "input": "$Array",
          "cond": { "$eq": [ "$$this.field1", "a" ] }
        }
      }
    }
  }}
])

Или „открийте отново колелото“, като използвате $reduce :

db.collection.aggregate([
  { "$project": {
    "total": {
      "$reduce": {
        "input": "$Array",
        "initialValue": 0,
        "in": {
          "$sum": [
            "$$value", 
            { "$cond": [{ "$eq": [ "$$this.field1", "a" ] }, 1, 0] }
        }
      }
    }
  }}
])

Или за това, което се опитвахте да направите с $unwind , вие всъщност $group отново, за да "преброите" колко съвпадения има:

db.collection.aggregate([
  { "$unwind": "$Array" },
  { "$match": { "Array.field1": "a" } },
  { "$group": {
    "_id": "$_id",
    "total": { "$sum": 1 }
  }}
])

Първите две форми са "оптималните" за съвременните среди на MongoDB. Окончателният формуляр с $unwind и $group е „наследена“ конструкция, която наистина не е била необходима за този тип операция от MongoDB 2.6, макар и с някои малко по-различни оператори.

В първите две ние основно сравняваме field1 стойността на всеки елемент от масива, докато той все още е масив. И двете $filter и $reduce са модерни оператори, предназначени да работят със съществуващ масив на място. Същото сравнение се прави за всеки един, като се използва агрегацията $eq оператор, който връща булева стойност въз основа на това дали дадените аргументи са "равни" или не. В този случай на всеки член на масива към очакваната стойност на "a" .

В случай на $filter , масивът всъщност остава непокътнат, с изключение на всички елементи, които не отговарят на предоставеното условие в "cond" се премахват от масива. Тъй като все още имаме „масив“ като изход, можем да използваме $size оператор за измерване на броя елементи на масива, останали след обработката на това филтърно условие.

$reduce от друга страна работи чрез елементите на масива и доставя израз върху всеки елемент и съхранена стойност на „акумулатор“, която инициализирахме с "initialValue" . В този случай същият $eq тестът се прилага в рамките на $cond оператор. Това е "троичен" или if/then/else условен оператор, който позволява на тестван израз, който връща булева стойност, да върне then стойност, когато е true или друго стойност при false .

В този израз връщаме 1 или 0 съответно и предоставя общия резултат от добавянето на тази върната стойност и текущия "акумулатор" "$$value" с $sum оператор, за да ги добавите заедно.

Окончателният формуляр използва $unwind върху масива. Това, което всъщност прави, е да деконструира членовете на масива, за да създаде "нов документ" за всеки член на масива и свързаните с него родителски полета в оригиналния документ. Това на практика „копира“ главния документ за всеки член на масива.

След като $unwind структурата на документите се променя към "по-плоска" форма. Ето защо след това можете да направите последващото $match етап на конвейер за премахване на несъвпадащите документи.

Това ни води до $group който се прилага, за да „събере обратно“ цялата информация, свързана с общ ключ. В този случай това е _id поле на оригиналния документ, което разбира се беше копирано във всеки документ, създаден от $unwind . Докато се връщаме към този „общ ключ“ като единичен документ, можем да „преброим“ останалите „документи“, извлечени от масива, използвайки $sum акумулатор.

Ако искаме да върнем оставащия „масив“, тогава можете да $push и изградете отново масива само с останалите членове:

  { "$group": {
    "_id": "$_id",
    "Array": { "$push": "$Array" },
    "total": { "$sum": 1 }
  }}

Но, разбира се, вместо да използвате $size в друг етап на конвейер можем просто все още да „броим“, както вече направихме с $sum




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Генерирайте PDF с библиотеката на JasperReports и MongoDB

  2. как да проверя от драйвер дали mongoDB сървърът работи

  3. Основната директория на Mongodb monogorestore трябва да бъде дъмп на една база данни

  4. Как да създадете потребител и да добавите роля в MongoDB

  5. Как правите SQL Like оператор в mongoDB, като използвате официалния C# драйвер