当前位置: 首页 > 知识库问答 >
问题:

条件/聚合:搜索数组字段中包含最新给定状态元素的所有完整文档

储国发
2023-03-14

我有这样的文档结构-

{
"_id" : "11223344",
"orderId" : "00001041",
"key" : "56h68ab4c876dbe1cd0b1ee"
"status" : [
    {
        "updatedTimeStamp" : ISODate("2017-06-01T16:05:42.737Z"),
        "orderStatus" : "INITIATED"
    },
    {
        "updatedTimeStamp" : ISODate("2017-06-01T16:05:42.737Z"),
        "orderStatus" : "CONFIRM_PAYMENT"
    },
    {
        "updatedTimeStamp" : ISODate("2017-06-01T16:07:36.797Z"),
        "orderStatus" : "RESTAURENT_CONFIRMATION_PENDING"
    },
    {
        "updatedTimeStamp" : ISODate("2017-06-01T16:20:36.798Z"),
        "orderStatus" : "ORDER_CONFIRMED"
    },
    {
        "updatedTimeStamp" : ISODate("2017-06-01T16:51:27.562Z"),
        "orderStatus" : "PREPARED"
    },
    {
        "updatedTimeStamp" : ISODate("2017-06-01T17:31:27.562Z"),
        "orderStatus" : "DISPATCHED"
    }
],
"customerDetails" : {
    "firstName" : "XXXX",
    "lastName" : "XXXXX",
    "emailId" : "xxxx_xxxx@gmail.com",
    "phoneNumber" : "XXXXXXXXX"
},
"amountPaid" : "250.0",
"orderDetails" : {blah... blah... blah...}
js lang-js prettyprint-override">db.order.aggregate([
  {$match: {key:"56h68ab4c876dbe1cd0b1ee"}},
  {$unwind: "$status"},
  {$project:{Id:"$_id",status:"$status.orderStatus", updatedTimeStamp:"$status.updatedTimeStamp"} },
  {$sort:{updatedTimeStamp:1} },
  {$group: {_id: "$Id", LatestStatus:{$last: "$status"}, updatedTimeStamp:{$last: "$updatedTimeStamp"} } },
  {$match:{"LatestStatus":"CONFIRM_PAYMENT"}},
 {$project:{Id:"$Id"}}
])

有人能用标准或聚合API帮助解决这个问题吗?*该查询中还有一个筛选器是“key”。

共有1个答案

赫连智
2023-03-14

您可以使用$expr(3.6mongo版本操作符)在常规查询中使用聚合函数。

比较查询运算符聚合比较运算符

使用$indexofarray运算符在status数组中查找$maxupdated timestamp元素,然后投影状态值,并与输入状态进行比较以检查值。

{
  "key":"56h68ab4c876dbe1cd0b1ee",
  "$expr":{
    "$eq":[
      {"$let":{
        "vars":{
          "status":{"$arrayElemAt":["$status",{"$indexOfArray":["$status.updatedTimeStamp",{"$max":"$status.updatedTimeStamp"}]}]}
        },
        "in":"$$status.orderStatus"
      }},
      "CONFIRM_PAYMENT"]
  }
}
Query query = new BasicQuery("{key:'56h68ab4c876dbe1cd0b1ee','$expr':{'$eq':[{$let:{vars:{status:{'$arrayElemAt':['$status',{'$indexOfArray':['$status.updatedTimeStamp',{'$max':'$status.updatedTimeStamp'}]}]}}, in:'$$status.orderStatus'}},'CONFIRM_PAYMENT']}}");
List<Document> results = mongoTemplate.find(query, Document.class);

Shell查询:

db.order.aggregate([ 
  { "$match" : { "key" : "56h68ab4c876dbe1cd0b1ee"}} , 
  { "$addFields" : {
    "cmpret" : { 
      "$eq" : [ 
        { "$let" : {
          "vars" : { "status" : { "$arrayElemAt" : [ "$status" , { "$indexOfArray" : [ "$status.updatedTimeStamp" , { "$max" : "$status.updatedTimeStamp"}]}]}} ,
          "in" : "$$status.orderStatus"
        }} , 
        "CONFIRM_PAYMENT"
      ]
    }
  }} , 
  { "$match" : { "cmpret" : true}} , 
  { "$project" : { "cmpret" : 0}}
])

Spring代码:

  AggregationOperation match1 = Aggregation.match(Criteria.where("key").is("56h68ab4c876dbe1cd0b1ee"));
        AggregationOperation addFields = new AggregationOperation() {
            @Override
            public Document toDocument(AggregationOperationContext aggregationOperationContext) {
                Document cmpret = Document.parse("{'$eq':[{$let:{vars:{status:{'$arrayElemAt':['$status',{'$indexOfArray':['$status.updatedTimeStamp',{'$max':'$status.updatedTimeStamp'}]}]}}, in:'$$status.orderStatus'}},'CONFIRM_PAYMENT']}}");
                return new Document("$addFields", new Document("cmpret", cmpret));
            }
        };

  AggregationOperation match2 =  Aggregation.match(Criteria.where("cmpret").is(true));

   AggregationOperation dropFields = new AggregationOperation() {
            @Override
            public Document toDocument(AggregationOperationContext aggregationOperationContext) {
                return new Document("$project", new Document("cmpret", 0));
            }
        };
   Aggregation aggregation = Aggregation.newAggregation(
                match1,
                addFields,
                match2,
                dropFields
    );

   AggregationResults<Document> results = mongoTemplate.aggregate(aggregation, "order", Document.class);
 类似资料:
  • 问题内容: 如何在上面的数组中松散搜索“ Last”一词? 上面的代码仅在指针与值中的所有内容完全匹配时才回显值的键,这是我不想要的。我想要这样的东西: 如果值包含单词“ Last”,我希望值的键回显。 问题答案: 要查找符合搜索条件的值,可以使用函数: 现在,数组将仅包含原始数组中包含单词 last (不区分大小写)的元素。 如果需要查找与条件匹配的值的键,则需要遍历数组: 现在,数组包含原始数

  • 我在一次采访中被问到以下问题。虽然我用n元树回答了这个问题,但有人告诉我这还不够好。所以,我很好奇,什么是它的最佳解决方案。 输入:整数数组:[2,3,7]和总和:10 输出:加起来等于和的所有数组元素组合(例如2、2、3、3、7等) 谢了小泰

  • 我在mongodb中有一个集合,如下所示。 MongoDB版本:4.0.13

  • 我试图在ElasticSearch中运行类似的字段查询:

  • 来自< code>$elementMatch的MongoDB文档: $elemMatch运算符将包含数组字段的文档与至少一个与所有指定查询条件匹配的元素匹配。 但是,如何将包含数组字段的文档与与查询匹配的所有元素进行匹配? 例如,我有这样的文档: 我需要匹配所有具有所有 如果我使用以下查询: 该文档将被匹配,因为至少有一个价格 我也试过这个,但它似乎不工作: 有没有办法排除查看所有价格而不是至少一

  • 问题内容: 示例数据: 还有一个示例查询: 首先返回击中的猫,然后返回狗,这就是我想要的。 但是 当您查询时,猫和狗的相关性得分相同。我希望能够考虑到该单词的前缀(并且可能在该字段中添加了其他几个单词),然后运行。 因此,如果我搜索: 要么 我应该得到cat / ID 1,但没有。 我发现使用可以实现多词短语,但不能实现多不完整的短语。并获得不完整的短语,但不能获得多个不完整的短语… 筛选文档确实