按数组的最后一个元素mongodb排序

时间:2017-06-22 06:48:59

标签: arrays mongodb sorting spring-boot

我试图通过上次互动对文档进行排序。 meta_data.access_times是一个数组,每次用户交互时都会更新,并且新的日期对象会附加到数组的最后一个元素。有没有办法按数组的最后一个元素排序?

尝试1:

private Aggregation makeQuery(String userId) {
     return newAggregation(
          match(Criteria.where("user_id").is(userId)),
          sort(Sort.Direction.DESC, "$meta_data.access_times"),
          group(Fields.fields().and("first_name", "$meta_data.user_data.first_name").and("last_name", "$meta_data.user_data.last_name").and("profile_pic", "$meta_data.user_data.profile_pic").and("user_id", "$user_id").and("access_times", "$meta_data.access_times"))
      );
    }

尝试2:

 private Aggregation makeQuery(String userId) {
        return newAggregation(
            match(Criteria.where("user_id").is(user_id)),
            group(Fields.fields().and("first_name", "$meta_data.user_data.first_name").and("last_name", "$meta_data.user_data.last_name").and("profile_pic", "$meta_data.user_data.profile_pic").and("user_id", "$user_id")).max("$meta_data.access_times").as("access_time"),
            sort(Sort.Direction.DESC, "access_time")
        );
    }

文档中的meta_data数组示例

"meta_data" : { "access_times" : [ 
            ISODate("2017-06-20T14:04:14.910Z"), 
            ISODate("2017-06-22T06:27:32.210Z"), 
            ISODate("2017-06-22T06:27:35.326Z"), 
            ISODate("2017-06-22T06:31:28.048Z"), 
            ISODate("2017-06-22T06:36:19.664Z"), 
            ISODate("2017-06-22T06:37:00.164Z")
        ] }

2 个答案:

答案 0 :(得分:2)

我通过使用$ unwind操作解决了这个问题。

 private Aggregation makeQuery(String userId) {
        return newAggregation(
            match(Criteria.where("user_id").is(userId)),
            unwind("$meta_data.access_times"),
            group(Fields.fields().and("first_name", "$meta_data.user_data.first_name").and("last_name", "$meta_data.user_data.last_name").and("profile_pic", "$meta_data.user_data.profile_pic").and("user_id", "$user_id")).max("$meta_data.access_times").as("access_time"),
            sort(Sort.Direction.DESC, "access_time")
        );
    }

答案 1 :(得分:1)

如果您不知道推送的元素是否已订购(例如,推送他的用户得分......),您可以按顺序使用$ push和$ sort要有一个有序数组,那么你可以按“find({userId:yourUseId} .sort(”metadata.access_time.0“: - 1)排序。

此解决方案假设您的数组在创建/更新时按$ sort排序:LINK

如果您确定Push不需要排序(例如,您正在为该用户推送Access_Date),您可以使用$运算符$ push和void $ sort(tnx Erdenezul) )。 LINK

理论上,如果find()只获取少量文档,则不需要数组“access_time”上的索引。否则,您只需添加{“metadata.access_time.0”:-1}的索引。

祝你好运!