2016-12-28 5 views
0

mongo dbの配列の要素を取得しようとしています。私は、だから私はので、現在私が使っ理由です一致しないために要素に比べて一致するように、より多くの要素をMongodbスライスと要素マッチングを使用する

{ 
"_id" : ObjectId("s4dcsd5s4d6c54s6d"), 
"items" : [ 
    { 
     type : "TYPE_1", 
     text : "blablabla" 
    }, 
    { 
     type : "TYPE_2", 
     text : "blablabla" 
    }, 
    { 
     type : "TYPE_3", 
     text : "blablabla" 
    }, 
    { 
     type : "TYPE_1", 
     text : "blablabla" 
    }, 
    { 
     type : "TYPE_2", 
     text : "blablabla" 
    }, 
    { 
     type : "TYPE_1", 
     text : "blablabla" 
    } 
] 
} 

を持っているのは、想像してみましょうパターン

と一致していない15個の最初の要素を取得したいと思いますnin。それは私が

db.history.find({ "_id" : ObjectId("s4dcsd5s4d6c54s6d")}, { "items" : { "$elemMatch" : { "type" : { "$nin" : [ "TYPE_2" , "TYPE_3"]}}}, "items" : { $slice : [0, 2]}}).pretty() 

を使用する場合私がしなければ次に

(私は、スライス後の要素の試合を置けば、同様の逆を)要素の一致が考慮されていないようです

をsimplifiyすることです:エラーがモンゴ

によってスローされます

db.history.find({ "_id" : ObjectId("s4dcsd5s4d6c54s6d")}, { "items" : { "$elemMatch" : { "type" : { "$nin" : [ "TYPE_2" , "TYPE_3"]}}, $slice : [0, 2]}}).pretty() 

あなたはどのように私ができる知っていますか行う?

どうもありがとう

答えて

1

それが唯一の最初の要素を返しますので、あなたはあなたのケースのための$elemMatchを使用することはできません。 documentationから:

$ elemMatchザ・$ elemMatch演算子は、クエリ結果から フィールドの内容は$ elemMatch条件に合致するだけ最初の要素 を含むように制限します。

あなたは、次の操作を行います集約クエリ実行できます。

  • が一致し、あなたの_id
  • マッチタイプ$nin配列内の項目ごとに1つのレコードを持っているあなたのitems配列をほどきますあなたの配列[ "TYPE_2" , "TYPE_3"]
  • 結果の数を制限する

クエリは次のとおりです。

db.history.aggregate([{ 
     $match: { 
      _id: ObjectId("s4dcsd5s4d6c54s6d") 
     } 
    }, { 
     $unwind: '$items' 
    }, { 
     $match: { 
      'items.type': { '$nin': ["TYPE_2", "TYPE_3"] } 
     } 
    }, 
    { $limit: 2 } 
]) 

それが与える:

{ "_id" : "s4dcsd5s4d6c54s6d", "items" : { "type" : "TYPE_1", "text" : "blablabla" } } 
{ "_id" : "s4dcsd5s4d6c54s6d", "items" : { "type" : "TYPE_1", "text" : "blablabla" } } 
+0

おかげであなたをbetrand。 – Geoffrey

+0

簡単な質問springdata mongodbを使用しますか?あなたが言ったことを実際に使用しようとしています。 '集合集約= newAggregation(一致(Criteria.where( 'id')。is(profileID))、unwind( 'items')、match(Criteria。( 'items.type')。nin(無視されたアイテムタイプ))、limit(3)、skip(1)); ' そして、私は次のようになります: ' {"集計": "__collection__"、 "パイプライン":{"" $一致 ":{" id ":" 5856dcf347816870aab76137 "}}、{" $ unwind ":" $ items "" $ {match}:{"items.type":{"$ nin":["TYPE_2"、 "TYPE_3"、 "TYPE_4"、 "TYPE_5"、 "TYPE_6"]}}}、{"$ 「制限」:3}、{"$ skip":0}]} アイデアはありますか? – Geoffrey

+0

_idにobjectId型を使用し、Stringではなく、これが問題の可能性があります。http://stackoverflow.com/questions/14346028/spring-data-mongodb-query-converts-string-to-objectid-automatically –

1

あなたが持っているフォームで配列を制限するための集約を使用する必要があります。 $ filterを使用して条件を適用し、$ sliceを使用して配列要素を制限します。

db.history.aggregate([{ 
    $match: { 
     _id: ObjectId("586309d6772c68234445f2a5") 
    } 
}, { 
    "$project": { 
     "items": { 
      "$slice": [{ 
        "$filter": { 
         "input": "$items", 
         "as": "item", 
         "cond": { 
          "$and": [{ 
           $ne: ["$$item.type", "TYPE_2"] 
          }, { 
           $ne: ["$$item.type", "TYPE_3"] 
          }] 
         } 
        } 
       }, 
       2 
      ] 
     } 
    } 
}]) 

サンプル出力:

{ "_id" : ObjectId("586309d6772c68234445f2a5"), "items" : [ { "type" : "TYPE_1", "text" : "blablabla" }, { "type" : "TYPE_1", "text" : "blablabla" } ] } 
関連する問題