【发布时间】:2017-10-24 10:04:51
【问题描述】:
我有以下问题。假设我有以下模型对象:
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));,它还会返回一个特定的页面,但在这种情况下,我无法手动构造“分页”结果,因为我不知道元素的总数。
你还有什么可以帮助我的想法吗?
提前致谢!
【问题讨论】:
-
Spring mongo 存储库实际上是 sh*t,我们使用它有一段时间了,但从未对它感到满意。然后我们切换到mongotemplate,现在它完美运行了,分页很简单,只需使用limit和skip即可。
-
mongoTemplate 可以是一个解决方案。问题是结果必须通过 REST 端点提供,该端点需要可导航链接(因此是分页结果)。不幸的是 mongoTemplate 不支持这个功能。
-
你可以实现你自己的分页我会在几分钟内写一个答案
标签: mongodb spring-boot mongorepository