2017-12-20 1 views
3

Ich habe Methode wie folgt:Wie überprüft man, ob der Wert mindestens einem Feld aus der Liste entspricht?

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; 

Dieser Code ineffizient aussieht, weil es den Zugang zu db so viel wie Feldarray Größe.

Gibt es eine Möglichkeit, es durch einzelne Abfrage zu ersetzen?

+0

Sie wollen eine 'OR' Anfrage? 'where crit1 OR crit2 ODER crit3' – AxelH

Antwort

3

mir scheint, dass Sie public Criteria orOperator(Criteria... criteria)

Es sollte etwas sein, verwenden könnte wie:

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()] 
     ) 
    ) 
); 

Dadurch wird eine Liste von Criteria erstellt, die zum Generieren einer Criteria-Instanz verwendet wird, die gültig ist, wenn ein Kriterium gültig ist (OR-Operation, ein wahr ist ausreichend).

+0

sieht aus wie trooth - ich werde überprüfen – gstackoverflow

4

Warum nicht Criteria::in Methode und eine Liste statt Iterate über das ganze Element passieren und Element überprüfen, indem Element, ich glaube, Sie brauchen nur das:

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

Neben dem Kommentar von @Veeram der Der erste Weg funktioniert, wenn Sie überprüfen wollen, ob ein Feld einen der Werte in Ihrer Liste enthalten kann, aber es scheint, dass Ihr Problem anders ist, was ich verstehe, Sie wollen einen Wert in mehreren Feldern überprüfen, um dieses Problem zu lösen Sie können verwenden:

//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 

Mit Streams können Sie verwenden:

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; 

zwar technisch korrekt, wenn Sie den Code ausführen werden Sie

org.springframework.data.mongodb.InvalidMongoDbApiUsageException erhalten: Wegen Beschränkungen von com.mongodb.BasicDBObject können Sie keinen zweiten '$ oder' Ausdruck als hinzufügen, der als '$ oder: [{"data.field2": "some_constant"}] angegeben wurde. Die Kriterien enthalten bereits '$ oder: [{"data.field1" : "some_constant"}]'.

MongoDB konformen Code:

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()]))); 

Ausgänge:

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

In operator funktioniert nicht, da Op eine Liste von Schlüsseln für eine Konstante abfragt. – Veeram

+0

oops das ist richtig @Veuram Ich denke, dass die OP-Felder nicht die richtigen Werte, lassen Sie mich einen tiefen Atemzug und lesen Sie es sorgfältig. –

+0

überprüfe meine Antwort @Veuram Ich denke, das kann helfen, die op –

Verwandte Themen