0

データベースにコレクションがあり、ほとんどのドキュメントには配列フィールドがあります。これらの配列には、正確に2 つの要素が含まれています。ここで、これらの配列要素がすべてクエリ配列の要素であるすべてのドキュメントを検索したいと考えています。

文書例:

{ a:["1","2"] },
{ a:["2","3"] },
{ a:["1","3"] },
{ a:["1","4"] }

クエリ配列:

["1","2","3"]

クエリ配列に「4」がないため、クエリは最初の 3 つのドキュメントを検索する必要がありますが、最後のドキュメントは検索しません。

期待される結果:

{ a:["1","2"] },
{ a:["2","3"] },
{ a:["1","3"] }

役に立つ答えを楽しみにしています:)。

4

3 に答える 3

3

サイズは静的であるため、両方の要素が [1,2,3] にあることを確認できます。

db.test.find(
  { $and: [ { "a.0": {$in: ["1","2","3"] } },
            { "a.1": {$in: ["1","2","3"] } } ] },
  { _id: 0, a: 1 }
)

>>> { "a" : [ "1", "2" ] }
>>> { "a" : [ "2", "3" ] }
>>> { "a" : [ "1", "3" ] }

編集: 動的に行うのは少し面倒です。集約フレームワークなしでは方法が思いつきません。一致したものを 0、一致しなかったものを 1 としてカウントし、最後に合計が != 0; であるすべてのグループを削除します。

db.test.aggregate(
  { $unwind: "$a" },
  { $group: { _id: "$_id", 
              a: { $push: "$a" },
              fail: { $sum: {$cond: { if: { $or: [ { $eq:["$a", "1"] },
                                                   { $eq:["$a", "2"] },
                                                   { $eq:["$a", "3"] }]
                                          },
                                      then: 0,
                                      else: 1 } } } } },
  { $match: { fail: 0 } },
  { $project:{ _id: 0, a: 1 } } 
)

>>> { "a" : [ "1", "3" ] }
>>> { "a" : [ "2", "3" ] }
>>> { "a" : [ "1", "2" ] }
于 2014-06-18T18:54:16.647 に答える
2

また、集約フレームワークなしでは不可能だと思います(要素数が動的な場合)。しかし、私はそれを行うより普遍的な方法を見つけました:

db.tests.aggregate({
  $redact: {
    $cond: {
      if: {$eq: [ {$setIsSubset: [ '$a', [ "1", "2", "3" ] ]}]},
      then: '$$KEEP',
      else: '$$PRUNE'
    }
  }
})
于 2016-09-10T09:30:12.850 に答える