简体   繁体   中英

Grouping in Spring Data MongoDB returns NULL _id when mapping to a class with composite key

I want to aggregate a collection of documents that match certain conditions, group them and map the output to a different class object. The aggregation works fine and I get the expected total but the _id field is always NULL.

I'm using spring-data-mongodb 2.1.11 and MongoDB 3.6.

This is the class to be aggregated:

@Document
public class LegOrder {

    public static class Key {
        @Indexed
        long itemId;

        long transactionId;
        ...
    }

    @Id
    private Key id;

    @Indexed
    private long brandId;

    private int units;
    ...
}

This is the aggregation output class:

@Document
public class ItemAggregation {

    public static class Key {
        @Indexed
        long itemId;

        @Indexed
        long brandId;
    }

    @Id
    private Key id;

    private long total;
    ...
}

My aggregation method:

public ItemAggregation aggregate(long itemId, long brandId) {
    MatchOperation matchStage = Aggregation.match(new Criteria().andOperator(
            Criteria.where("id.itemId").is(itemId),
            Criteria.where("brandId").is(brandId)
    ));

    GroupOperation groupStage = Aggregation.group("id.itemId", "brandId")
            .sum("units").as("total")
            ...
            ;

    Aggregation aggregation = Aggregation.newAggregation(matchStage, groupStage);

    return mongoTemplate.aggregate(aggregation, LegOrder.class, ItemAggregation.class).getUniqueMappedResult();
}

The executed query in MongoDB:

[
  {
    "$match": {
      "$and": [
        { "_id.itemId": 1 },
        { "brandId": 2}
        ]
    }
  },
  {
    "$group": {
      "_id": {
        "itemId": "$_id.itemId",
        "brandId": "$brandId"
      },
      "total": { "$sum": "$units" }
    }
  }
]

If I run this query in the mongo shell the _id field is properly populated.

Any idea how to achieve it?

Thank you

Sorry for the late response. I faced this issue now and found this solution. My aggregation output in console is

{
        "_id" : {
                "ownerId" : BinData(3,"xkB0S9Wsktm+tSKBruv6og=="),
                "groupbyF" : "height"
        },
        "docs" : [
                {
                        "id" : ObjectId("5fe75026e211c50ef5741b31"),
                        "aDate" : ISODate("2020-12-26T15:00:51.056Z"),
                        "value" : "rrr"
                }
        ]
}
{
        "_id" : {
                "ownerId" : BinData(3,"AAAAAAAAAAAAAAAAAAAAAA=="),
                "groupbyF" : "weight"
        },
        "docs" : [
                {
                        "id" : ObjectId("5fe6f702e211c50ef5741b2f"),
                        "aDate" : ISODate("2020-12-26T08:40:28.742Z"),
                        "value" : "55"
                },
                {
                        "id" : ObjectId("5fe6f6ade211c50ef5741b2e"),
                        "aDate" : ISODate("2020-12-26T08:38:58.098Z"),
                        "value" : "22"
                }
        ]
}

The mapping that worked for me

import lombok.Data;

@Data
public class AggregationLatest2Type{
    private String ownerId;
    private String key;
    private List<Doc> docs;
    
    @Data
    public  class Doc{
            private String _id;
            private Date aDate;
            private String value;
            
            
        }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM