2015-11-16 16 views
5

yılında $ veya Mongo toplama $ grup $ cond $ nin nasıl kullanılır:

db.collectionName.aggregate(
{ 
    "$group": { 
    "_id":'$created_at', 
    "count": {"$sum": 1}, 
    "count_failure": { 
     "$sum": { 
      "$cond": [ 
       { 
       "$id": 
        { "$in": [ 0,100,101,102,103,104,105 ] } 
       }, 
       1, 
       0 
       ] 
      } 
     } 
    } 
} 
) 

Ama hata diyor ki: Invalid operator "$id"

Sözdiziminde neyin var? Ya da yanlış bir şekilde yazıyorum.

Şu anda bu elde ediyorum:

db.collectionName.aggregate(
{ 
    "$group": { 
    "_id":'$created_at', 
    "count": {"$sum": 1}, 
    "count_failure": { 
     "$sum": { 
      "$cond": [ 
       { 
       "$or":[ 
        { "$eq": [ "$id", 0 ] }, 
        { "$eq": [ "$id", 100 ]}, 
        { "$eq": [ "$id", 101 ]}, 
        { "$eq": [ "$id", 102 ]}, 
        { "$eq": [ "$id", 103 ]}, 
        { "$eq": [ "$id", 104 ]}, 
        { "$eq": [ "$id", 105 ]} 
       ] 
       }, 
       1, 
       0 
       ] 
      } 
     } 
    } 
} 
) 

cevap

8

$setIsSubset üzerinde karşılaştırma kullandığınız $or koşulu daha kısa bir seçenektir, Yine de, yaptığınız şeyi yapmak için hala geçerli.

$setIsSubset numaralı tek yakalama, her bağımsız değişkenin bir dizidir, bu nedenle tek öğeyi tek bir öğe dizisi olarak dönüştürmeniz gerekir.

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

Ya da tercihen, daha sonra $anyElementTrue ile yerine tekil değer karşı argümanlar dizisini maç: Bu yetmez $map kullanmasına imkan sağlayacak

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 yerine argümanlar baştan bir başa nerede Bir diziye tekil olarak zorlamaktan ziyade tekille eşleşir.

Ve tabii

ya form esas o zaman sadece gerekli $not ile mantığını tersine çevirebilir $cond için true/false tedarik edildiğinden:

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

Gerçekten sen ona nasıl baktığınıza bağlıdır, ancak sadece tedarik edildiği gibi argümanlar sonra orijinal formda $or ile hiçbir şey kazanamazsınız. Biraz daha temiz ve "yazması daha kolay" gibi görünebilir, ancak tipik olarak, toplama mantığına doğrudan böyle bir mantığı "yazmam", ancak ilk etapta düz bir listeye dayanarak yapının o kısmını oluşturmamayı tercih ederim:

yani

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

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

ve sonra sadece boru hattı tanımında yeniden eşlenen dizi içeriği kullanarak: ona bak ne olursa olsun yolu, hepsi sadece veri yapılarını hatırlıyorum ve temel süreçleri var

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

manipüle etmek için. Hem boru hattı işlemenin içinde hem de boru hattı yapımında.

+0

1 yol biraz zor. 2. bir tanesi kolaydır. Her ne kadar kolay $ veya $ grubunda olmalı? Umut mongo bu özelliği serbest bırakır. –

+0

@SomnathMuluk Sanırım üç yaklaşımı göstererek "3. yol" demek istedim ve kayıt için bütün kodlarımın böyle bir şey yapması mantıklı bir yaklaşım olduğu için böyle yapıyor. Eğer '$ in 'yan tümcesini istediğinizi kastediyorsanız, ilk etapta' $ cond 'ile beslenmesini istediğinizi düşünün, bu nedenle böyle bir işlemin sözdizimi tam olarak nedir? Karşılaştırmak istediğiniz alanı nerede belirlersiniz? Böyle bir öneriyle bir [JIRA] (https://jira.mongodb.org/secure/Dashboard.jspa) göndermeyi kabul edersiniz. –

+1

Evet 2. ve 3. olanlar çok kolay. Ve zaten https://jira.mongodb.org/browse/SERVER-6146 –

0

ben $ bir toplama boru hattı operatörü olmadığını düşünüyorum.

+0

"$ In" yerine "$ setIsSubset" nasıl kullanılır? –

+0

Sözdizimi: '{$ setIsSubset: [, ]}'. "id" öğenizi bir matrise koymanız gerekir.Ama ikinci düşüncede, bunun en iyi çözüm olmadığını düşünüyorum. – hecnabae

0

Önce projede kullanarak $id$map bir listesini oluşturmak ve sonra aşağıda grubunda setIsSubset kullanmalıdır:

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