У меня следующая проблема. Допустим, у меня есть следующий объект модели:
class Person {
String id;
String firstName;
String lastName;
Map<String, String> properties;
}
В карту свойств можно вставить любое свойство, ограничений нет.
Вышеупомянутый объект сохраняется в MongoDB, который выглядит следующим образом:
public interface PersonRepo extends MongoRepository<Person, String> {
}
Когда человек сохраняется в хранилище, Map<String, String> properties
сглаживается. Например, если у нас есть следующий объект:
Person: {
id := 1;
firstName := John,
lastName := Doe,
properties := {
age: 42
}
}
документ, сохраненный в MongoRepository, будет следующим:
Person: {
id := 1;
firstName := John,
lastName := Doe,
age := 42
}
Теперь моя проблема в том, что я должен искать объекты на основе (например), есть ли у них определенное свойство или нет. Допустим, мне нужны все лица, для которых определено свойство возраста. Одно важное дополнительное требование состоит в том, что я должен возвращать постраничный результат.
Я пытался использовать
findAll(Example<Person> example, Pageable pageable)
Но это не работает по какой-то причине. Я подозреваю, что дело в том, что мой объект модели и документ MongoDB имеют разные структуры.
Я также пытался использовать QueryDsl (здесь у вас есть пример: http://www.baeldung.com/queries-in-spring-data-mongodb), но также безуспешно, а также для меня это решение не является элегантным (необходимо поддерживать сгенерированные классы и тому подобное. Также у меня есть ощущение, что это не сработает из-за моего члена объекта Map<String, String> properties
).
Другое решение, которое пришло мне в голову и было бы достаточно элегантным, состоит в том, чтобы иметь следующую функцию:
@Query(value = "?0")
Page<Query> findByQuery(String query, Pageable pageable)
В этом случае я мог бы вручную построить запрос, и мне не пришлось бы жестко кодировать ключ, по которому я запускаю поиск. Мой вопрос теперь в том, как установить значение запроса, чтобы оно было именно моим первым параметром? В примере, показанном выше, я получаю следующую ошибку
java.lang.ClassCastException: java.lang.String cannot be cast to com.mongodb.DBObject
Еще одним решением может быть использование mongoTemplate
и запроса с учетом некоторого Criteria
, как в следующем примере:
final Query query = new Query();
query.addCriteria(Criteria.where("age").regex(".*"));
mongoTemplate. find(query, Person.class);
Проблема с этим решением заключается в том, что оно возвращает список объектов вместо постраничного результата. Он также возвращает определенную страницу, если я добавляю query.with(new PageRequest(3, 2));
, но в этом случае я не могу вручную построить результат "выгружаемого по страницам", потому что я не знаю общего количества элементов.
У вас есть другие идеи, которые могли бы мне помочь?
Заранее спасибо!