我有以下问题。假设我有以下模型对象:
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));
但在这种情况下,我无法手动构造“分页”结果,因为我不知道元素的总数。
您还有其他可以帮助我的想法吗?
提前致谢!