用户投影字段作为 Spring Boot 2 和 MongoDB 中 MatchOperation 的标准
User projected field as criteria for a MatchOperation in Spring Boot 2 and MongoDB
我花了几个小时寻找一种方法来做到这一点,但我没有找到任何有用的方法。
我会尽量简短。我有几个步骤的聚合。第一步我分组,然后我用表达式投影几个字段(进行一些计算),最后我想使用这些投影字段(我的计算结果)作为下一个匹配阶段的条件:
Cond condOperation = ConditionalOperators.when(Criteria.where("productRulesValues.maxTerm").lte("$availableYears"))
.thenValueOf("$productRulesValues.maxTerm")
.otherwise("$availableYears");
TypedAggregation<ProductRulesValues> aggregationProducts = Aggregation.newAggregation(ProductRulesValues.class,
Aggregation.group("productType")
.last("$$ROOT").as("productRulesValues"),
project("productRulesValues")
.andExpression("productRulesValues.maxAge - [0]", formHipooWizard.getAge()).as("availableYears"),
project("productRulesValues")
.and(condOperation).as("duration"),
new MatchOperation(Criteria.where("productRulesValues.maxTerm").is("$duration"))
);
最接近我正在寻找的答案是 ,但它使用了 DBObject 的旧方法。
我试过用 org.bson.Document 改变 DBObject 的方法,因为它现在使用的是运气不好(它抱怨 $where 子句)。参考:
我不太明白的一件事是,当我定义第一个条件时,使用文档属性和投影属性没有问题。
如果不是:
new MatchOperation(Criteria.where("productRulesValues.maxTerm").is("$duration")
我用文字过滤持续时间,它的工作原理非常棒,因此持续时间具有正确的内存值:
new MatchOperation(Criteria.where("duration").is(30)
有什么解决方法吗?
谢谢!
这是预期的行为。
第一个条件中的聚合表达式允许您比较文档字段。因此在 3.6 之前,所有匹配查询都与静态值和文档字段进行比较。
从 3.6 开始,您必须使用特殊运算符 $expr
,它允许在匹配查询中使用聚合表达式。
spring 尚不支持 $expr。
您必须使用投影来添加包含比较的新字段,然后使用匹配操作和额外的投影来删除比较字段。
Cond condOperation = ConditionalOperators.when(Criteria.where("productRulesValues.maxTerm").lte("$availableYears"))
.thenValueOf("$productRulesValues.maxTerm")
.otherwise("$availableYears");
TypedAggregation<ProductRulesValues> aggregationProducts = Aggregation.newAggregation(ProductRulesValues.class,
Aggregation.group("productType")
.last("$$ROOT").as("productRulesValues"),
project("productRulesValues")
.andExpression("productRulesValues.maxAge - [0]", formHipooWizard.getAge()).as("availableYears"),
project("productRulesValues")
.and(condOperation).as("duration").and(ComparisonOperators.Eq.valueOf("productRulesValues.maxTerm").equalOf("duration")).as("comp"),
new MatchOperation(Criteria.where("comp").is(true)),
project().andExclude("comp");
);
请注意,从 3.4 开始支持带排除项的项目。
我花了几个小时寻找一种方法来做到这一点,但我没有找到任何有用的方法。
我会尽量简短。我有几个步骤的聚合。第一步我分组,然后我用表达式投影几个字段(进行一些计算),最后我想使用这些投影字段(我的计算结果)作为下一个匹配阶段的条件:
Cond condOperation = ConditionalOperators.when(Criteria.where("productRulesValues.maxTerm").lte("$availableYears"))
.thenValueOf("$productRulesValues.maxTerm")
.otherwise("$availableYears");
TypedAggregation<ProductRulesValues> aggregationProducts = Aggregation.newAggregation(ProductRulesValues.class,
Aggregation.group("productType")
.last("$$ROOT").as("productRulesValues"),
project("productRulesValues")
.andExpression("productRulesValues.maxAge - [0]", formHipooWizard.getAge()).as("availableYears"),
project("productRulesValues")
.and(condOperation).as("duration"),
new MatchOperation(Criteria.where("productRulesValues.maxTerm").is("$duration"))
);
最接近我正在寻找的答案是
我试过用 org.bson.Document 改变 DBObject 的方法,因为它现在使用的是运气不好(它抱怨 $where 子句)。参考:
我不太明白的一件事是,当我定义第一个条件时,使用文档属性和投影属性没有问题。
如果不是:
new MatchOperation(Criteria.where("productRulesValues.maxTerm").is("$duration")
我用文字过滤持续时间,它的工作原理非常棒,因此持续时间具有正确的内存值:
new MatchOperation(Criteria.where("duration").is(30)
有什么解决方法吗?
谢谢!
这是预期的行为。
第一个条件中的聚合表达式允许您比较文档字段。因此在 3.6 之前,所有匹配查询都与静态值和文档字段进行比较。
从 3.6 开始,您必须使用特殊运算符 $expr
,它允许在匹配查询中使用聚合表达式。
spring 尚不支持 $expr。
您必须使用投影来添加包含比较的新字段,然后使用匹配操作和额外的投影来删除比较字段。
Cond condOperation = ConditionalOperators.when(Criteria.where("productRulesValues.maxTerm").lte("$availableYears"))
.thenValueOf("$productRulesValues.maxTerm")
.otherwise("$availableYears");
TypedAggregation<ProductRulesValues> aggregationProducts = Aggregation.newAggregation(ProductRulesValues.class,
Aggregation.group("productType")
.last("$$ROOT").as("productRulesValues"),
project("productRulesValues")
.andExpression("productRulesValues.maxAge - [0]", formHipooWizard.getAge()).as("availableYears"),
project("productRulesValues")
.and(condOperation).as("duration").and(ComparisonOperators.Eq.valueOf("productRulesValues.maxTerm").equalOf("duration")).as("comp"),
new MatchOperation(Criteria.where("comp").is(true)),
project().andExclude("comp");
);
请注意,从 3.4 开始支持带排除项的项目。