字段“idFields”必须是累加器对象

问题描述 投票:0回答:1

我正在尝试使用 Spring Data Mongo 来获取文档集合中某些字段的平均值。我有一个通过 Atlas 搜索进行搜索的管道,然后是一个执行平均值的小组阶段。

  {
    "_id": {"$oid": "65ea0c9d638cd57f51c22cb7"},
    "listing": {
      "listingId": 709834373,
      "listDate": {"$date": "2023-10-12T00:00:00.000Z"},
      "price": {
        "currencyCode": "USD",
        "value": 1000
      },
    }
  }
    public Optional<SummaryData> searchResultsSummaryData(SearchFilter searchFilter) {
        SearchOperation searchOperation = buildSearchOperationFromFilter(searchFilter);

        SearchAggregation searchAggregation = SearchAggregation.builder()
                .searchOperation(searchOperation)
                .build();

        Document aggregationDoc = new Document();
        mongoConverter.write(searchAggregation, aggregationDoc);

        GroupOperation groupOperation = group("listing.price.value").avg("$avg(listing.price.value)").as("avgPrice");

        Document groupDoc = new Document();
        mongoConverter.write(groupOperation, groupDoc);
        log.debug("groupDoc: {}", groupDoc.toJson());
        Document groupStage = new Document("$group", groupDoc);

        Document projectDocDetail = new Document("avgPrice", 1);
        Document projectDoc = new Document("$project", projectDocDetail);

        MongoCollection<Document> collection = mongoOperations.getCollection(LISTING_DOCUMENT.collection());


        List<Document> aggList = List.of(aggregationDoc, groupStage, projectDoc);
        log.debug("aggList: {}", toJson(aggList));
        AggregateIterable<Document> aggregationResult = collection.aggregate(aggList);

        Document summaryDocument = aggregationResult.first();
        if (summaryDocument == null) {
            return Optional.empty();
        } else {
            return Optional.of(defaultMongoConverter.read(SummaryData.class, summaryDocument));
        }
    }

但是当我运行这个时,我得到了这个异常:

com.mongodb.MongoCommandException: Command failed with error 40234 (Location40234): 'The field 'idFields' must be an accumulator object' on server pl-1-us-west-2.c8foo.mongodb.net:1037. The full response is {"ok": 0.0, "errmsg": "The field 'idFields' must be an accumulator object", "code": 40234, "codeName": "Location40234", "$clusterTime": {"clusterTime": {"$timestamp": {"t": 1719546021, "i": 8}}, "signature": {"hash": {"$binary": {"base64": "rOfPFKpgglg5DigfTjeL2n1qgeg=", "subType": "00"}}, "keyId": 7329363855287517191}}, "operationTime": {"$timestamp": {"t": 1719546021, "i": 8}}}
    at com.mongodb.internal.connection.ProtocolHelper.getCommandFailureException(ProtocolHelper.java:205) ~[mongodb-driver-core-4.11.2.jar:na]
    at com.mongodb.internal.connection.InternalStreamConnection.receiveCommandMessageResponse(InternalStreamConnection.java:454) ~[mongodb-driver-core-4.11.2.jar:na]
    at com.mongodb.internal.connection.InternalStreamConnection.sendAndReceive(InternalStreamConnection.java:372) ~[mongodb-driver-core-4.11.2.jar:na]
    at com.mongodb.internal.connection.UsageTrackingInternalConnection.sendAndReceive(UsageTrackingInternalConnection.java:114) ~[mongodb-driver-core-4.11.2.jar:na]
    at com.mongodb.internal.connection.DefaultConnectionPool$PooledConnection.sendAndReceive(DefaultConnectionPool.java:765) ~[mongodb-driver-core-4.11.2.jar:na]

如果我反序列化管道,我会收到以下查询:

[
  {
    "$search": {
    ...
    }
  },
  {
    "$group": {
      "idFields": {
        "originalFields": [
          {
            "synthetic": false,
            "field": {
              "raw": "listing.price.value",
              "name": "price.value",
              "target": "listing.price.value"
            }
          }
        ],
        "syntheticFields": []
      },
      "operations": [
        {
          "op": "AVG",
          "key": "avgPrice",
          "reference": "$avg(listing.price.value)"
        }
      ]
    }
  },
  {
    "$project": {
      "avgPrice": 1
    }
  }
]

我可以手写一个小组赛阶段来完成我想要的事情:

        $group: {
            _id: null,
           avgPrice: { $avg: "$listing.price.value" }
        }

但是 Spring Data 的序列化方式完全不同。

我尝试将各种字段名称传递给

group()
方法,但基本上得到了相同的错误。

任何帮助将不胜感激。

java mongodb spring-data spring-data-mongodb
1个回答
0
投票

您不应该在

group
方法中传递任何内容。

GroupOperation groupOperation = Aggregation.group().avg("listing.price.value").as("avgPrice");

生成的阶段是,

{
"$group":
    {
    "_id": null,
    "avgPrice":
        {
        "$avg": "$listing.price.value"
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.