简体   繁体   English

如何检查该值是否等于列表中的至少一个字段?

[英]How to check that value equals at least one field from list?

I have method like this: 我有这样的方法:

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;

This code looks inefficient because it access to db so much how fieldArray size. 这段代码看起来效率低下,因为它访问db这么多fieldArray的大小。

Is there way to replace it using single query? 有没有办法用单个查询替换它?

Why not using Criteria::in method and pass a List instead of Iterate over all the element and check element by element, I think you need just this : 为什么不在方法中使用Criteria ::并传递List而不是迭代所有元素并逐个元素检查,我认为你需要这样:

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

Beside the comment of @Veeram the first way will work if you want to check if one field can hold one of the values in your list, but it seems that your problem is different, what i understand, you want to check a value exit in multiple fields, to solve this issue you can use : 除了@Veeram的注释之外,如果你想检查一个字段是否可以容纳列表中的一个值,第一种方式将起作用,但似乎你的问题不同,我理解,你想检查一个值退出多个字段,解决这个问题你可以使用:

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

With streams you can use : 使用流可以使用:

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;

Although technically correct when you run the code you will get 虽然在运行代码时技术上是正确的,但您会得到

org.springframework.data.mongodb.InvalidMongoDbApiUsageException: Due to limitations of the com.mongodb.BasicDBObject, you can't add a second '$or' expression specified as '$or : [ { "data.field2" : "some_constant"}]'. org.springframework.data.mongodb.InvalidMongoDbApiUsageException:由于com.mongodb.BasicDBObject的限制,您无法添加第二个'$或'表达式,指定为'$或:[{“data.field2”:“some_constant” }]”。 Criteria already contains '$or : [ { "data.field1" : "some_constant"}]'. 标准已包含'$或:[{“data.field1”:“some_constant”}]'。

Mongodb compliant code: 符合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()])));

Outputs: 输出:

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

Seems to me that you could use public Criteria orOperator(Criteria... criteria) 在我看来,你可以使用public Criteria orOperator(Criteria... criteria)

It should be something like : 它应该是这样的:

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

This will create a list of Criteria that will be used to generate an Criteria instance that will be valid if one criteria is valid (OR operation, one true is enough). 这将创建一个Criteria列表,用于生成Criteria实例,如果一个条件有效(OR操作,一个true就足够了),该实例将有效。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何检查对象是否具有至少一个不为null的字段? - How to check if an object has at least one field that is not null? 一个列表至少包含另一个列表中的一个值(Java 8) - A list contains at least one value from another list (Java 8) 如何检查列表是否至少包含一个元素而不循环 - How to check if list has at least one element without looping 如何在枚举值上检查等于? - How to check equals on enum value? 如何断言某个字符串至少包含列表中的一个值<string> ?</string> - How to assert that some String contains at least one value from the List <String>? Java:如何在执行操作之前检查Java中的可观察列表以确保其至少包含一个值? - Java: How can I check an observable list in Java to make sure it contains at least one value before completing an action? 如何检查一个树集至少包含另一个树集中的一个项目 - How to check a treeset contains at least one items from another treeset 检查列表是否至少包含另一个 - 枚举 - Check if list contains at least one of another - enums 如何从具有公共字段的另一个对象列表中为一个对象列表的字段设置值? - How to set value for a field of one list of object from another list of object having a common field? 如何检查一维数组中的一个值是否至少为一个,其他所有值为零? - How to check if one value in a 1-D array is at least one, and all others are zero?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM