我在Spring Data Mongodb中使用QueryDSL谓词。但是,我面临着必须使用MongoTemplate查询API的情况(例如过滤要从Mongo中获取的字段)。这是一个简单的例子:
public Stream<MyModel> findSummary(Predicate predicate){
Query query = new Query();
query.fields.include("field1").include("field2");
return mongoTemplate.stream(query, MyModel.class);
}
我想将我的谓词转换为标准,以便我可以执行以下操作:
Query query = new Query();
query.addCriteria(XXXXX.toCriteria(predicate));
但是我找不到这样的实用类。
我发现可以访问QueryDSL Predicate,因此我开始实现自定义访问者(com.mysema.query.types.Visitor),但Criteria API并非为此目的而设计:例如,实现简单&#34;和&#34; QueryDSL的运算符(com.mysema.query.types.Ops#AND)必须变成类似
的运算符<result of left argument visit assumed to be a Criteria>.and("<path of right argument>").<operator of right argument>(<result of right argument visit>);
有人可以提出一种方法来使QueryDSL Predicates和Spring Data Mongodb Query互操作吗?
由于
贝努瓦
答案 0 :(得分:0)
我遇到了同样的问题,但在互联网上没有找到解决此问题的任何解决方案。经过多次反复试验,我实施了一个自定义解决方案,该解决方案在我的项目中运行良好,可能对其他人有所帮助。
注意
使用的版本:
实现
首先创建一个类,该类扩展 org.springframework.data.mongodb.repository.support.SpringDataMongodbQuery
并使用 createQuery(Predicate predicate)
修饰符覆盖 public
方法。
public class CustomSpringDataMongodbQuery<T> extends SpringDataMongodbQuery<T> {
public CustomSpringDataMongodbQuery(MongoOperations operations, Class<? extends T> type) {
super(operations, type);
}
@Override
public Document createQuery(Predicate predicate) {
return super.createQuery(predicate);
}
}
现在创建一个实现 org.springframework.data.mongodb.core.query.CriteriaDefinition
的类。
public class DocumentCriteria implements CriteriaDefinition {
private final Document criteriaObject;
public DocumentCriteria(Document criteriaObject) {
this.criteriaObject = criteriaObject;
}
@Override
public Document getCriteriaObject() {
return criteriaObject;
}
@Override
public String getKey() {
return null;
}
}
现在您可以使用这两个类从谓词中获取查询。
Document document = new CustomSpringDataMongodbQuery<>(mongoTemplate, MyModel.class).createQuery(predicate);
Query query = Query.query(new DocumentCriteria(document));
投影查询
如果你想使用QClass字段进行投影,那也是可以的。
在 CustomSpringDataMongodbQuery 类中,添加方法
public Query createQuery(Predicate filter, List<Path<?>> fields) {
QTuple qTuple = Projections.tuple(fields.toArray(new Path[0]));
return createQuery(filter, qTuple, QueryModifiers.EMPTY, Collections.emptyList());
}
并传递路径列表(QClass 字段)以及谓词
使用投影和分页查询
您可以使用
为上述方法添加分页public Query createQuery(Predicate filter, List<Path<?>> fields, int page, int size, List<OrderSpecifier<?>> orderSpecifiers) {
QTuple qTuple = Projections.tuple(fields.toArray(new Path[0]));
QueryModifiers queryModifiers = new QueryModifiers((long) size, (long) (page - 1) * size);
return createQuery(filter, qTuple, queryModifiers, orderSpecifiers);
}
希望这对所有想要使 QueryDSL Predicates 和 Spring Data Mongodb Query 互操作的人有所帮助。
欢迎提出任何建议!!