2017-12-20 6 views
3

私はこのような方法があります:その値をチェックする方法は、リストから少なくとも1つのフィールドと同じですか?

for (String fieldName : fieldArray) { 
     Query query = new Query(); 
     query.addCriteria(Criteria.where("data." + fieldName).is("some_constant")); 
     if (mongoTemplate.find(query, DataPoint.class).size() > 0) { 
      return true; 
     } 
} 
return false; 

それがアクセスそんなにどのようfieldArrayサイズをDBへので、このコードは非効率的になります。

単一のクエリを使用して置き換える方法はありますか? @Veeramのコメントのほかに

query.addCriteria(
    Criteria.where("data." + fieldName).in(fieldArray) 
); 

+0

「OR」リクエストが必要ですか? 'where crit1 OR crit2 OR crit3' – AxelH

答えて

3

あなたはそれがあるべきpublic Criteria orOperator(Criteria... criteria)

を使用することができますように私には思える何かのように:

List<Criteria> criterias = new ArrayList<>(); 
for (String fieldName : fieldArray) { 
    //Create the criterias like you want 
    criterias.add(Criteria.where("data." + fieldName).is("some_constant")); 
} 

Query query = new Query(
    new Criteria().orOperator(
     criterias.toArray(//convert the list into an Criteria[] for the varargs parameter 
      new Criteria[criterias.size()] 
     ) 
    ) 
); 

これは、1つの条件が有効である(OR演算、1つが真である)場合に有効となるCriteriaインスタンスを生成するために使用されるCriteriaのリストを作成します。

+0

トロロスのように見えます – gstackoverflow

4

Criteria::in方法を使用して、すべての要素の上に代わりに反復のリストを渡すと、要素ごとにチェックしないのはなぜ、私はあなただけでこれを必要だと思います最初の方法は、1つのフィールドがリストの値の1つを保持できるかどうかを確認したい場合には機能しますが、問題は異なると思われます。この問題を解決するために、あなたは使用することができます:

//Consider you want to check in multiple fields 
List<String> fieldArray = Arrays.asList("field1", "field2", "field3"); 

// First you have to create a list of Criteria (multiple conditions) 
List<Criteria> listOfCondition = new ArrayList<>(); 
for (String fieldName : fieldArray) { 
    listOfCondition.add(
      Criteria.where("data." + fieldName).is("some_constant") 
    ); 
} 

//The add them to the query. 
Criteria criteria = new Criteria(); 
for (Criteria c : listOfCondition) { 
    criteria = criteria.orOperator(c); 
} 
Query query = new Query(); 
query.addCriteria(criteria); 
//Then execute your query just one time 
あなたが使用できるストリームで

:限界へ 期限:

List<String> fieldArray = Arrays.asList("field1", "field2", "field3"); 
Criteria principaleCriteria = new Criteria(); 
fieldArray.stream() 
     .map(fieldName -> Criteria.where("data." + fieldName).is("some_constant")) 
     .forEach(criteria -> principaleCriteria.orOperator(criteria)); 
Query query = new Query(); 
query.addCriteria(principaleCriteria); 
return mongoTemplate.count(query, DataPoint.class) > 0; 

あなたは、コードを実行するときは、

org.springframework.data.mongodb.InvalidMongoDbApiUsageExceptionを取得しますが、技術的に正しいですcom.mongodb.BasicDBObjectの2番目の '$ or'式に$または:[{"data.field2": "some_constant"}]と指定した を追加することはできません。条件にはすでに '$または:[{"data.field1" : "some_constant"}]'が含まれています。

のMongoDB準拠したコード:

List<String> fieldArray = Arrays.asList("field1", "field2", "field3"); 
Criteria principaleCriteria = new Criteria(); 
List<Criteria> orExpressions = fieldArray.stream() 
       .map(fieldName -> Criteria.where("data." + fieldName).is("some_constant")) 
       .collect(toList()); 
Query query = new Query(); 
     query.addCriteria(principaleCriteria.orOperator(orExpressions.toArray(new Criteria[orExpressions.size()]))); 

出力:

{ "$or" : [ { "data.field1" : "some_constant"} , { "data.field2" : "some_constant"} , { "data.field3" : "some_constant"}]} 
+1

オペレータは、Opが定数のキーのリストを照会しているときに、動作しません。 – Veeram

+0

oopsこれは正しい@Veeram私は、OPチェックフィールドに値が正しくないと思います。深呼吸して注意深く読ませてください。 –

+0

私の答えをチェック@Veeramこれは、操作を助けることができると思う –

関連する問題