我们尝试使用$ project(聚合)和包含字段(查询),但它只包含Id和Filtered字段。我们的预期结果是文档中的所有字段以及按区域设置(动态密钥)过滤的嵌入文档。
示例:
categories:[{
_id: 1,
categoryNumber: "12345",
locale: {
en_US: {
name: "Category Name in US"
},
fr_FR: {
name: "Category Name in French"
}
}
},
{
_id: 2,
categoryNumber: "6789",
locale: {
en_GB: {
name: "Category Name in UK"
}
}
}]
Expected Result:
Filter records by locale: en_US(Embedded document key)
[{
_id: 1,
categoryNumber: "12345",
locale: {
en_US: {
name: "Category Name in US"
}
}
}]
查询:
AggregationOperation matchOperaion = match(where(Constants.ID).is(clientProdTypeId));
AggregationExpression aggregationExpression = (AggregationOperationContext) -> {
Map<String, Object> conditionMap = new HashMap<>();
conditionMap.put("input", "$locale.en_US.name");
conditionMap.put("as", Constants.NAME);
conditionMap.put("cond", new BasicDBObject());
return new BasicDBObject("$filter", conditionMap);
};
AggregationOperation projectionOperation;
projectionOperation = project().and(aggregationExpression).as(Constants.METADATA)
.andInclude(Constants.CLIENT_ID, Constants.PRODUCT_TYPE_ID,Constants.STATUS);
AggregationResults<CategoryDTO> result;
try {
result = mongoOperations.aggregate(newAggregation(matchOperaion, projectionOperation),
Category.class, CategoryDTO.class);
} catch (IllegalArgumentException | DataAccessException e) {
LOGGER.error("Error while fetching client product type", e);
}
return result.getUniqueMappedResult();
答案 0 :(得分:1)
而不是$project
使用$addFields。 $project
仅传递指定字段,$addFields
传递所有字段以及新/计算/字段。
答案 1 :(得分:1)
您可以在3.4
版本中使用以下聚合表达式。
$objectToArray
将locale
转换为键值对,并将$filter
转换为语言环境输入,$arrayToObject
转换回动态键。
AggregationExpression aggregationExpression = (AggregationOperationContext) -> {
Map<String, Object> conditionMap = new HashMap<>();
conditionMap.put("input", new BasicDBObject("$objectToArray", "$locale"));
conditionMap.put("as", "result");
conditionMap.put("cond", new BasicDBObject("$$result.k", "en_US"));
return new BasicDBObject("$arrayToObject", new BasicDBObject("$filter", conditionMap));
};
答案 2 :(得分:0)
db.collection.find({locale.en_US:{$exists : true}});