【发布时间】:2021-05-24 01:34:16
【问题描述】:
我有下面的 mongoDB 聚合,它在我的 mongodb 集合项中过滤测试数组。
样本集合项:{,...tests:[ {} , {"someField":"yesIamHere"} ] }
以下查询运行良好,仅返回包含 someField 的测试集合
db.getCollection('yourcollection')
.aggregate([
{"$match": {"tests.someField": {"$exists": true}}},
{ $project:{"tests": {"$filter": {"input": "$tests", "as": "item",
"cond": {"$ne": ["$$item.someField", undefined]}}}}
},
])
然而,
虽然使用 java BasicDBObject 将 "undefined" 作为字符串而不是 JS undefined
BasicDBObject projectionFilterInput=new BasicDBObject("input","$tests")
.append("as", "item")
.append("cond",new BasicDBObject("$ne", Arrays.asList("$$item.someField","undefined")));
因此,这解释了 "cond": {"$ne": ["$$item.vidaptorCode", "undefined"]}}}} "undefined" 而不是 undefined。因此,这不会按预期过滤项目。
在 mongodb java 驱动程序库中是否为这个特定的undefined 值定义了任何常量?这是主要问题。
谁好奇...
为什么我不使用 ODM?
实际上我们确实使用 Spring Data for MongoDB,但它不支持这种聚合cond。
MatchOperation matchStage = Aggregation.match(new Criteria("tests.someField").exists(true));
ProjectionOperation projection = Aggregation.project("tests");
Aggregation aggregation
= Aggregation.newAggregation(matchStage, projection);
AggregationResults<LabConfiguration> output
= mongoTemplate.aggregate(aggregation, "yourcollection", YourClass.class);
Morphia ODM
我喜欢 Morphia 流畅的语法,但是它们使用的注释与 Spring Data Mongo 不同,并且其依赖的 MongoDB 库也不同。简而言之,两个 ODM 不能一起工作。
最大的问题是你需要实现 BasicDAO<C,K> 的存储库实现,它不是很实用,它是面向 mongo 的,Spring Data Mongo 在 MongoRepository<C,K> 方面做得很好
Projections filterProjection = projection(
"tests",
expression(
"$filter",
new BasicDBObject("input","$tests")
.append("as", "item")
.append("cond",new BasicDBObject("$ne", Arrays.asList("$$item.someField","undefined")))
)
);
因此,我最终使用了 Mongo 驱动程序基本语法来解决这个问题,这就是为什么我需要将 undefined 传递给 BasiDBObject 而不是作为双引号覆盖的字符串。
我也愿意听取您的总体建议。我们现在拥有的是QueryDSL 和Spring Data for MongoDB。
【问题讨论】:
-
您不能在聚合的
$filter操作中检查“未定义” - 使用$ifNull聚合运算符构造cond的条件。 -
@prasad_ 感谢您的评论,我认为 ifNull 不是一回事。我们在某些文档中根本没有该字段。未定义检查适用于数据库工具,必须有办法
-
嗨@DavutGürbüz,Java 使用原始类型并且无法理解未定义的javascript,它总是将其作为字符串值。我同意@prasad 的建议,官方文档指出$ifNull
covers the undefined value as well as missing field。请查看docs.mongodb.com/manual/reference/operator/aggregation/ifNull -
如果你一定不想使用上面的建议,总是有这个 hack 可以将 json 直接转换为 DBObject,但是它更多的是 hack 而不是实现,并且不能保证它会工作百分之几。检查
https://stackoverflow.com/questions/16333549/converting-json-structure-to-basicdbobject/48234498 -
嗨@RahulKumar,谢谢。真的行。我期待像 $ifNotNull 之类的东西 :)
标签: java mongodb aggregation-framework