java.lang.IllegalArgumentException:在MongoDB中执行聚合的无效引用 [英] java.lang.IllegalArgumentException: Invalid reference performing aggregation in MongoDB

查看:1596
本文介绍了java.lang.IllegalArgumentException:在MongoDB中执行聚合的无效引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在收集中的文档为:

{
    "_id": ObjectId("5ab273ed31fa764560a912f8"),
    "hourNumber": 21,
    "errorSegments": [{
        "agentName": "agentX"
    },
    {
        "agentName": "agentY"
    }]
}

我正在尝试执行以下操作Spring Boot中的聚合函数,我要检索与代理匹配的特定时间的 errorSegments,该代理在mongo shell中可以正常工作:

I am trying to perform following aggregation function in spring boot where i want to retrieve "errorSegments" of a particular hour that matches an agent , which is working fine in mongo shell :

正在运行的shell:

Working shell :

db.errorsegment.aggregate([{
    "$match": {
        "hourNumber": 21,
        "errorSegments.agentName": "agentX"
    }
},
{
    "$project": {
        "errorSegments": {
            "$filter": {
                "input": "$errorSegments",
                "as": "e",
                "cond": {
                    "$eq": ["$$e.agentName",
                    "agentX"]
                }
            }
        }
    }
},
{
    "$unwind": "$errorSegments"
},
{
    "$replaceRoot": {
        "newRoot": "$errorSegments"
    }
}])

因此它仅提供输出,这是期望的结果:

So it provides output only , which is desired result :

{ "agentName" : "agentX" }

但是我下面的代码在春天给出了错误:

But my following code in spring gives error :

MatchOperation match = Aggregation.match(Criteria.where("hourNumber").is(21).and("errorSegments.agentName").is("agentX"));

        ProjectionOperation project = Aggregation.project()
                  .and(new AggregationExpression() {

                      @Override
                        public DBObject toDbObject(AggregationOperationContext context) {

                          DBObject filterExpression = new BasicDBObject();
                          filterExpression.put("input", "$errorSegments");
                          filterExpression.put("as", "e");
                          filterExpression.put("cond", new BasicDBObject("$eq", Arrays.<Object> asList("$$e.agentName","agentX")));

                          return new BasicDBObject("$filter", filterExpression);
                      } }).as("prop");


        UnwindOperation unwind = Aggregation.unwind("$errorSegments");

        ReplaceRootOperation replaceRoot = Aggregation.replaceRoot("$errorSegments");

        Aggregation aggregation = Aggregation.newAggregation(match,project,unwind,replaceRoot);

        AggregationResults<ErrorSegment> errorSegments = mongoOps.aggregate(aggregation, SegmentAudit.class , ErrorSegment.class);

以下是日志:

java.lang.IllegalArgumentException: Invalid reference 'errorSegments'!
    at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:99) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.aggregation.ExposedFieldsAggregationOperationContext.getReference(ExposedFieldsAggregationOperationContext.java:71) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.aggregation.UnwindOperation.toDBObject(UnwindOperation.java:95) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.aggregation.AggregationOperationRenderer.toDBObject(AggregationOperationRenderer.java:56) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.aggregation.Aggregation.toDbObject(Aggregation.java:580) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1567) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na]
    at org.springframework.data.mongodb.core.MongoTemplate.aggregate(MongoTemplate.java:1502) ~[spring-data-mongodb-1.10.3.RELEASE.jar:na]


推荐答案

错误源是您与筛选器操作一起使用的别名。应该是 errorSegments 而不是 prop ,但是您还会遇到其他问题。使用字段名,即$前缀不正确。

The source of error is the alias that you use with filter operation. It should be errorSegments instead of prop but you you other problems too. Use fieldname i.e $ prefix is not right.

这是更新的聚合。您可以使用 $ filter 助手。

Here is the updated aggregation. You can use $filter helper.

MatchOperation match = Aggregation.match(Criteria.where("hourNumber").is(21).and("errorSegments.agentName").is("agentX"));
ProjectionOperation project = Aggregation.
            project().and(ArrayOperators.Filter.filter("errorSegments")
                    .as("e")
                    .by(ComparisonOperators.Eq.valueOf(
                            "e.agentName")
                            .equalToValue(
                                    "agentX")))
                    .as("errorSegments");
UnwindOperation unwind = Aggregation.unwind("errorSegments");
ReplaceRootOperation replaceRoot = Aggregation.replaceRoot("errorSegments");
Aggregation aggregation = Aggregation.newAggregation(match,project,unwind,replaceRoot);

下面是生成的查询。

[
  {
    "$match": {
      "hourNumber": 21,
      "errorSegments.agentName": "agentX"
    }
  },
  {
    "$project": {
      "errorSegments": {
        "$filter": {
          "input": "$errorSegments",
          "as": "e",
          "cond": {
            "$eq": [
              "$$e.agentName",
              "agentX"
            ]
          }
        }
      }
    }
  },
  {
    "$unwind": "$errorSegments"
  },
  {
    "$replaceRoot": {
      "newRoot": "$errorSegments"
    }
  }
]

这篇关于java.lang.IllegalArgumentException:在MongoDB中执行聚合的无效引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆