简体   繁体   中英

Mongodb Aggregate (Java/Spring) query to fetch last subelement

I have following structure names Discussion. I want to fetch the last message in a discussion by a user. I tried following incomplete Spring MongoDB query, could you please let me know how to fetch just one message (sorted by lastmodifieddate) per discussion or find the discussions where a user is the recipient of the last message in the conversation.

Aggregation aggr = newAggregation(
            match(Criteria.where("participants").regex(Pattern.compile(userid))),
                unwind("messages"),
                match(new Criteria().orOperator(Criteria.where("messages.touserId").is(userid),Criteria.where("messages.fromuserId").is(userid))),
                sort(Direction.DESC, "messages.lastModifiedDate"),
                group("_id").push("messages").as("messages"),
                project("_id","messages")
                );

{
  "_id": {
    "$oid": "57c2d7c8e4b0bcf181b7db0a"
  },
  "_class": "xxxxx",
  "participants": [
    "56893b22e4b0e8d1c6a25783",
    "56893bb6e4b0e8d1c6a25785",
    "577c2f6ee4b09ccb44d14415"
  ],
  "messages": [
    {
      "_id": {
        "$oid": "57c2d7c8e4b0bcf181b7db08"
      },
      "fromuserId": "577c2f6ee4b09ccb44d14415",
      "fromuser": "xxxx",
      "touserId": "56893b22e4b0e8d1c6a25783",
      "touser": "Bloreshop1",
      "message": "Check Product Price",
      "isMute": false,
      "index": 1,
      "createDate": {
        "$date": "2016-08-28T12:23:36.037Z"
      },
      "lastModifiedDate": {
        "$date": "2016-08-28T12:23:36.037Z"
      },
      "createdBy": "xxxx",
      "lastModifiedBy": "xxxxx"
    },
    {
      "_id": {
        "$oid": "57c2d7c8e4b0bcf181b7db09"
      },
      "fromuserId": "577c2f6ee4b09ccb44d14415",
      "fromuser": "xxxxxx",
      "touserId": "56893bb6e4b0e8d1c6a25785",
      "touser": "Bloreshop2",
      "message": "Check Product Price",
      "isMute": false,
      "index": 2,
      "createDate": {
        "$date": "2016-08-28T12:23:36.302Z"
      },
      "lastModifiedDate": {
        "$date": "2016-08-28T12:23:36.302Z"
      },
      "createdBy": "xxxxx",
      "lastModifiedBy": "xxx"
    }
  ],
  "discussionTopic": "Check Product Price",
  "messageCount": 2,
  "createDate": {
    "$date": "2016-08-28T12:23:36.318Z"
  },
  "lastModifiedDate": {
    "$date": "2016-08-28T12:23:36.318Z"
  },
  "createdBy": "xxxx",
  "lastModifiedBy": "xxxxx"
}

You are looking for $slice(aggregation) . Current release 1.9.5 version doesn't support slice.

Aggregation aggr = newAggregation(
        match(Criteria.where("participants").regex(Pattern.compile(userid))),
        unwind("messages"),
        match(new Criteria().orOperator(Criteria.where("messages.touserId").is(userid), Criteria.where("messages.fromuserId").is(userid))),
        sort(Direction.DESC, "messages.lastModifiedDate"),
        group("_id").push("messages").as("messages"),
        project("_id").and("messages").project("slice", 1));

Unreleased Version (2.x) supports slice

Aggregation aggr = newAggregation(
        match(Criteria.where("participants").regex(Pattern.compile(userid))),
        unwind("messages"),
        match(new Criteria().orOperator(Criteria.where("messages.touserId").is(userid), Criteria.where("messages.fromuserId").is(userid))),
        sort(Direction.DESC, "messages.lastModifiedDate"),
        group("_id").push("messages").as("messages"),
        project("_id").and("messages").slice(1));

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