API критериев для построения динамического запроса c в Spring-Data Mongodb - PullRequest
0 голосов
/ 11 февраля 2020

У меня есть список, который я использую, чтобы найти некоторые идентификаторы из БД. Список содержит что-то вроде следующего:

List<someObject> filterCriteria =[{"name":"somename", "value":"someValue"},{"value":"randomValue"}]

Это дает мне два отдельных фильтра, один из которых выполняет поиск по nameValue, а другой - только по значению. Я строю два критерия, используя эти значения: критерии значения имени:

where("person.name")
                .is(filterItem.getName())
                .andOperator(Criteria.where("person.value").regex(filterItem.getValue(), "i"))

и фильтр значений как:

where("person.value")
                .regex(someString, "i");

Я выполняю итерацию в отдельной службе, чтобы получить их в виде списка критериев как :

List<Criteria> criteriaList = new ArrayList<>();
       filterCriteria.forEach(x -> criteriaList.add(criteriaMapper.mapFilterCriteria()));

Я пытаюсь использовать Criteria API весной для создания одного запроса, который эквивалентен запросу mon go с вышеуказанными критериями

db.collection.find({$or:[{$and:[{"person.value":"jOfQIv5QMairziy"}
,{"person.name":"zzDLpQSBAA"}]},{"person.value":"re3bMfZAIDZHFPj"}]});

Я невозможно сформировать запрос на запись. Я столкнулся с API QueryBuilder, но не могу понять, как его использовать. Любая помощь будет очень полезна

1 Ответ

0 голосов
/ 12 февраля 2020

Вы можете использовать $elemMatch, что лучше соответствует вашим требованиям:

List<someObject> filterCriteria =[{"name":"somename", "value":"someValue"},{"value":"randomValue"}];
List<Criteria> criterias = new ArrayList<Criteria>();

for(someObject filterItem: filterCriteria) {
    //You may impement condition: If name not exists, put only value
    //Criteria.where("person").elemMatch(
    //    Criteria.where("value").is(filterItem.getName())
    //);
    criterias.add(
        Criteria.where("person").elemMatch(
            Criteria.where("name").is(filterItem.getName())
                .and("value").is(filterItem.getValue())
        )
    );
}

Query query   = Query.query(new Criteria().orOperator(
                    criterias.toArray(new Criteria[criterias.length])));
List<SomeClass> result = mongoTemplate.find(query, SomeClass.class);

Эквивалентно

db.collection.find({
  "$or": [
    {
      "person": {
        "$elemMatch": {
          "value": "jOfQIv5QMairziy"
        }
      }
    },
    {
      "person": {
        "$elemMatch": {
          "name": "zzDLpQSBAA",
          "value": "re3bMfZAIDZHFPj"
        }
      }
    }
  ]
})
...