Spring Data Mongo中为数组运算符结果设别名实现对象合并
MongoDB聚合管道转Spring Data Mongo代码问题
我正在尝试将MongoDB聚合管道查询转换为Spring Data MongoDB代码。
目标MongoDB聚合管道
{ $addFields: { orders:{ $map: { input: "$orders", as: "order", in: { $mergeObjects: [ "$$order", { instance: { $first: { $filter: { input: "$instances", as: "instance", cond: { $eq: [ "$$order.instance.docKey", "$$instance._id" ] } } } } } ] } } } } }
尝试的代码及问题
我编写了以下代码,但无法为ArrayOperators.first运算符返回的对象设置别名(即instance: { .... }):
AddFieldsOperation addInstanceFieldOp = Aggregation.addFields() .addFieldWithValue("orders", mapItemsOf("orders") .as("order") .andApply(ObjectOperators.MergeObjects.mergeValuesOf("order") .mergeWithValuesOf( ArrayOperators.First.first( filter("instances") .as("instance") .by( ComparisonOperators.Eq.valueOf("order.instance.docKey") .equalTo("instance._id") )) ) )).build();
解决方案
要实现为$first结果设置instance别名的需求,需要将first的结果包装成包含instance键的对象,再与原order对象合并。修改后的代码如下:
方法一:使用Document包装
AddFieldsOperation addInstanceFieldOp = Aggregation.addFields() .addFieldWithValue("orders", mapItemsOf("orders") .as("order") .andApply(ObjectOperators.MergeObjects.mergeValuesOf("order") .mergeWith(new Document("instance", ArrayOperators.First.first( filter("instances") .as("instance") .by(ComparisonOperators.Eq.valueOf("order.instance.docKey") .equalTo("instance._id")) ) )) ) ).build();
方法二:使用AggregationExpression构造
AddFieldsOperation addInstanceFieldOp = Aggregation.addFields() .addFieldWithValue("orders", mapItemsOf("orders") .as("order") .andApply(ObjectOperators.MergeObjects.mergeValuesOf("order") .mergeWith((AggregationExpression) ctx -> new Document("instance", ArrayOperators.First.first( filter("instances") .as("instance") .by(ComparisonOperators.Eq.valueOf(ctx.get("order") + ".instance.docKey") .equalTo(ctx.get("instance") + "._id")) ) )) ) ).build();
核心逻辑:原代码直接将first的结果传入mergeWithValuesOf,但我们需要的是带instance键的对象结构,因此用Document将first表达式包装成{ instance: ... },再合并到原order对象中,这样就能匹配目标管道的结构。
内容的提问来源于stack exchange,提问作者Haider
相关产品推荐
相关产品推荐

