Java 当使用Spring Data Mongo聚合mongodb中的组时,如何获取非空数组字段的元素计数?
我在一个名为Java 当使用Spring Data Mongo聚合mongodb中的组时,如何获取非空数组字段的元素计数?,java,mongodb,spring-data-mongodb,Java,Mongodb,Spring Data Mongodb,我在一个名为mail\u test的集合中拥有以下文档。其中一些具有标记字段,该字段是一个数组: /* 1 */ { "_id" : ObjectId("601a7c3a57c6eb4c1efb84ff"), "email" : "aaaa@bbb.com", "content" : "11111" } /* 2 */ { "_id&
mail\u test
的集合中拥有以下文档。其中一些具有标记
字段,该字段是一个数组:
/* 1 */
{
"_id" : ObjectId("601a7c3a57c6eb4c1efb84ff"),
"email" : "aaaa@bbb.com",
"content" : "11111"
}
/* 2 */
{
"_id" : ObjectId("601a7c5057c6eb4c1efb8590"),
"email" : "aaaa@bbb.com",
"content" : "22222"
}
/* 3 */
{
"_id" : ObjectId("601a7c6d57c6eb4c1efb8675"),
"email" : "aaaa@bbb.com",
"content" : "33333",
"tags" : [
"x"
]
}
/* 4 */
{
"_id" : ObjectId("601a7c8157c6eb4c1efb86f4"),
"email" : "aaaa@bbb.com",
"content" : "4444",
"tags" : [
"yyy",
"zzz"
]
}
有两个文档具有非空标记,因此我希望结果为2。
我使用以下语句汇总并获得正确的标记计数
:
db.getCollection('mail_test').aggregate([{$group:{
"_id":null,
"all_count":{$sum:1},
"tag_count":{"$sum":{$cond: [ { $ne: ["$tags", undefined] }, 1, 0]}}
//if replace `undefined` with `null`, I got the tag_count as 4, that is not what I want
//I also have tried `$exists`, but it cannot be used here.
}}])
结果是:
{
"_id" : null,
"all_count" : 4.0,
"tag_count" : 2.0
}
我使用java中的spring data mongo来实现这一点:
private void test(){
Aggregation agg = Aggregation.newAggregation(
Aggregation.match(new Criteria()),//some condition here
Aggregation.group(Fields.fields()).sum(ConditionalOperators.when(Criteria.where("tags").ne(null)).then(1).otherwise(0)).as("tag_count")
//I need an `undefined` instead of `null`,or is there are any other solution?
);
AggregationResults<MailTestGroupResult> results = mongoTemplate.aggregate(agg, MailTest.class, MailTestGroupResult.class);
List<MailTestGroupResult> mappedResults = results.getMappedResults();
int tag_count = mappedResults.get(0).getTag_count();
System.out.println(tag_count);//get 4,wrong
}
private void test(){
聚合agg=Aggregation.newAggregation(
Aggregation.match(new Criteria()),//此处有一些条件
Aggregation.group(Fields.Fields()).sum(ConditionalOperators.when(Criteria.where(“tags”).ne(null)).then(1)。否则(0)).as(“tag_count”)
//我需要一个'undefined'而不是'null',或者还有其他解决方案吗?
);
AggregationResults=mongoTemplate.aggregate(agg,MailTest.class,MailTestGroupResult.class);
List mappedResults=results.getMappedResults();
int tag_count=mappedResults.get(0).getTag_count();
System.out.println(tag_count);//获取4,错误
}
我需要一个
未定义的而不是null
,但我不知道如何做,或者是否有其他解决方案?您可以使用聚合运算符检查字段标记是否存在,并在查询的$group
阶段使用以下构造之一(要计算标签计数
值):
两者都返回相同的结果(如您发布的).为什么需要未定义的?我认为未定义的和空的都不应该用于检查字段的不存在。我同意,但我不知道任何其他解决方案。你的建议是什么?我发布了两种可能性作为答案-其中一种可以使用。你是对的。但是如何用java编写它呢?我尝试过这样做:Aggregation.group(Fields.Fields()).sum(ConditionalOperators.when(Criteria.where(“tags.size”).gt(0)).then(1).否则(0)).as(“tag\u count”)
结果是正确的,但我仍然希望明确排除空值。我不知道如何在这里使用$ifNull
。“…我仍然希望明确排除空值".你是说一个文档可以有标记:null
?现在没有。但我想让情况变得更复杂一点,这样我就可以在将来获得更多的技能来进行更复杂的聚合。我想知道如何严格地将mongodb脚本翻译成java代码。现在,没有。在这种情况下,上面两个就可以了。你就是我们ing Spring Data MongoDB(使用MongoDB Java驱动程序)-查找API文档(适当的版本).我通常只通过尝试浏览API和图表。另一个选项是,您可以使用带有两个方面的$facet
阶段-一个带有标记,一个用于所有。第一个方面可以有一个匹配阶段,它将过滤没有标记字段的文档。然后计算文档。第二个方面只计算文档。这将很容易编写代码使用Spring数据API。这消除了组阶段及其所有复杂条件。
"tag_count":{ "$sum": { $cond: [ { $gt: [ { $size: { $ifNull: ["$tags", [] ] }}, 0 ] }, 1, 0] }}
// - OR -
"tag_count":{ "$sum": { $cond: [ $eq: [ { $type: "$tags" }, "array" ] }, 1, 0] }