2015-11-16 5 views
5

を使用する方法:

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

しかし、エラーが言う:Invalid operator "$id"

構文に何が問題なのですか?あるいは、私は間違ってクエリを書いています。私は$に集約パイプライン演算子はないと思われる

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

答えて

8

$setIsSubsetの比較は、使用している$or条件よりも短いオプションであり、あなたがやっていることをやることはまだ基本的には有効ですが。

$setIsSubsetの唯一のキャッチは、各引数が配列なので、単一の要素を単一の要素配列として変換する必要があることです。

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で、代わりに特異値に対する引数の配列に一致する:これは$mapを使用して十分に簡単である

$mapはむしろに引数を横断さ
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 
       ] 
      } 
     } 
    }} 
]) 

を単数形を強制的に配列に入れるのではなく、単数形に一致させる。

そしてもちろんの

いずれかの形式は、本質的に、あなただけの必要 $notとロジックを逆にすることができます $condtrue/falseを供給しているのは:

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で元のフォームよりも何も得られません。それはちょっときれいに見えるかもしれませんが、「タイプするのが簡単ですが、一般的には、そのようなロジックを集計パイプラインに直接入力するのではなく、まず最初に単純なリストに基づいて構造の部分を生成します:

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

あなたは、それを見て、それはすべて単なるデータ構造だ覚えて、あなたが基本的なプロセスを持っているどのような方法:

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

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

そしてちょうどパイプライン定義で再マッピングされた配列の内容を使用して、すなわち

操作のために。パイプライン処理の内部とパイプラインの構築自体の両方で。

+0

第1のやや難しいです。 2番目は簡単です。簡単な$または$グループが必要ですか?ホンコンはこの機能をリリースします。 –

+0

@SomnathMuluk 3つのアプローチが示されているとすれば、「第3の方法」を意味すると思います。 '$ in'節が必要な場合は、最初に' $ cond'にフィードするように要求していると考えてください。そのような操作の構文はなんですか?あなたは比較したいフィールドをどこで指定しますか?あなたはそのような提案と共に[JIRA](https://jira.mongodb.org/secure/Dashboard.jspa)を投稿することを歓迎します。 –

+1

はい、2,3番目のものは簡単です。すでに提案がhttps://jira.mongodb.org/browse/SERVER-6146 –

0

は現在、私はすることによって、これを達成しています。

+0

「$ In」の代わりに「$ setIsSubset」を使用するにはどうすればよいですか? –

+0

構文: '{$ setIsSubset:[]}'。 要素 "id"を行列に入れる必要があります。しかし、第二の考えでは、それは最善の解決策ではないと私は思う。 – hecnabae

0

まず、プロジェクトで使用して$id$mapのリストを作成し、以下のようにグループでsetIsSubsetを使用する必要があります。

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 
     ] 
     } 
    } 
    } 
}]) 
関連する問題