java - MongoDB Aggregation - 如何使用 spring-data-mongodb 将查询表达式应用到匹配阶段?
问题描述
我有带有动态字段的文档,我需要为给定的复杂查询条件找到匹配记录的计数
示例实体
@Document(collection = "UserAttributes")
public class UserAttributesEntity {
@Id
@Getter
private String id;
@NotNull
@Size(min = 1)
@Getter @Setter
private String userId;
@NotNull
@Getter @Setter
private Map<String, Object> attributes = new HashMap<>();
}
示例数据
{
"_id" : ObjectId("6164542362affb14f3f2fef6"),
"userId" : "89ee6942-289a-48c9-b0bb-210ea7c06a88",
"attributes" : {
"age" : 61,
"name" : "Name1"
}
},
{
"_id" : ObjectId("6164548045cc4456792d5325"),
"userId" : "538abb29-c09d-422e-97c1-df702dfb5930",
"attributes" : {
"age" : 40,
"name" : "Name2",
"location" : "IN"
}
}
预期的查询表达式
"((attributes.name == 'Name1' && attributes.age > 40) OR (attributes.location == 'IN'))
$match 的 MongoDB 聚合查询如下,但是通过 spring mongo db api 不可用:
{
$expr:
{
"$and": [{
"$gt": ["$attributes.age", 40]
}, {
"$eq": ["$attributes.name", "Name2"]
}]
}
}
我在这里错过了什么吗?
库使用:org.springframework.data:spring-data-mongodb:3.1.1
解决方案
您可以实现自己的AggregationOperation
来处理您的不同条件。还没有尝试过我自己的代码,但它应该是这样的:
AggregationOperation myMatch (List<Document> conditions) {
return new AggregationOperation() {
@Override
public String getOperator() {
return "$match";
}
@Override
public Document toDocument(AggregationOperationContext context) {
return new Document("$match",
new Document("$expr",
new Document("$and", conditions)
)
);
}
};
}
并以这种方式调用它(以匹配您的问题查询):
void callMyMatch() {
myMatch(List.of(
new Document("$gt", List.of("$attributes.age", 40)),
new Document("$eq", List.of("$attributes.name", "Name2"))
));
}
推荐阅读
- reactjs - 如何在本机反应中获得视图 wrt 视口的位置?
- python - 用于多处理的酸洗双重装饰函数
- docker-compose - 使用 WSL-2 和 Docker 在 PhpStorm 中设置 PHPUnit:无法解析 PHPUnit 版本输出:无法打开输入文件
- java - 使用 ActionListener 的退出菜单不起作用
- flutter - 断言失败:布尔表达式不能为空(对于文档快照数据)
- c# - C# 中 BigInteger 除法和小数乘法的语法
- javascript - useState、UseRef 或 useMemo,我应该更喜欢哪个
- c++ - 我正在尝试用 C++ 解决最大面积直方图问题。但现在我面临分段错误并且无法解决它
- php - Gettext 没有在 Debian 10 中翻译 PHP
- mpandroidchart - Android,在使用 MPAndroidChart 绘制图形时,有没有办法指定 X 轴间距?