【问题标题】:Maintain order as original document while using addToSet in MongoDb在 MongoDb 中使用 addToSet 时保持原始文档的顺序
【发布时间】:2021-07-09 04:33:16
【问题描述】:

我阅读了文档,发现 addToSet 不保证顺序。 但是有什么办法可以将订单保留为原始文档。 我的查询是:-

    aggregate([{$match: {
      $or:[{"Name.No":"119"},{"Name.No":"120"}]
    }}, {$project: {
      x:{$objectToArray:"$Results"}
    }},{$unwind: "$x"},{$group: {_id: "$x.k", distinctVals: {$addToSet: "$x.v.TCR"}}}])

样本数据:

{"Name" : {"No." : "119","Time" : "t"},
"Results":{"K1" : {"Counters" : x, "TCR" : [{"Name" : "K11", "Result" : "PASSED"}, 
                                             {"Name" : "K12","Result" : "FAILED"},
                                             {"Name" : "K13","Result" : "PASSED"}]
                    },
            "K2" : {"Counters": y, "TCR" : [{"Name" : "K21","Result" : "PASSED"},              
                                            {"Name" : "K22","Result" : "PASSED"}]
                      
                    }
            
           }
}

} 工作2;

 {"Name" : {"No." : "120","Time" : "t1"},
"Results":{"K1" : {"Counters" : x, "TCR" : [{"Name" : "K11", "Result" : "PASSED"}, 
                                             {"Name" : "K12","Result" : "PASSED"},
                                             {"Name" : "K13","Result" : "FAILED"}]
                    },
            "K3" : {"Counters": y, "TCR" : [{"Name" : "K31","Result" : "PASSED"},              
                                            {"Name" : "K32","Result" : "PASSED"}]
                      
                    }
            
           
}

} 预期;

 {"Name" : {"No." : "119-120","Time" : "lowest(t,t1)"},
"Results":{"K1" : {"Counters" : x, "TCR" : [{"Name" : "K11", "Result" : "PASSED"}, 
                                             {"Name" : "K12","Result" : "PASSED"},
                                             {"Name" : "K13","Result" : "PASSED"}]
                    },
            "K2" : {"Counters": y, "TCR" : [{"Name" : "K21","Result" : "PASSED"},              
                                            {"Name" : "K22","Result" : "PASSED"}]
                      
                    },
             "K3" : {"Counters": y, "TCR" : [{"Name" : "K31","Result" : "PASSED"},              
                                            {"Name" : "K32","Result" : "PASSED"}]
                      
                    }
            
           
}

} 我想保持与原始文档相同的顺序,而且每次文档都会更改,所以我无法根据任何参数进行排序。

【问题讨论】:

  • 您能否在查询中添加示例数据mongoplayground.net
  • 如何定义顺序?假设您输入的是[20, 10, 20]。你想得到什么输出? [10, 20] 还是 [20,10]?来自@turivishal 的解决方案给出了[20,10]
  • 添加了现在有问题的示例数据。

标签: mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:
  • 使用$objectToArray将结果对象转换为数组格式
  • $unwind解构Results数组
  • $unwind解构Results.v.TCR数组
  • $match 过滤PASSED 结果
  • $group by Results.k 并获得第一个Name,获得第一个Counters,构造Results.v.TCR 的数组
  • $group by null 得到最小值Time,构造No的唯一数组,在键值对中构造Results数组,$reduce迭代TCR的循环并删除重复文档
  • $project 显示必填字段,使用 $arrayToObjectResults 数组转换为对象,将 No 数组转换为字符串并使用“-”连接
db.collection.aggregate([
  { $addFields: { Results: { $objectToArray: "$Results" } } },
  { $unwind: "$Results" },
  { $unwind: "$Results.v.TCR" },
  { $match: { "Results.v.TCR.Result": "PASSED" } },
  {
    $group: {
      _id: "$Results.k",
      Name: { $first: "$Name" },
      Counters: { $first: "$Results.v.Counters" },
      TCR: { $push: "$Results.v.TCR" }
    }
  },
  {
    $group: {
      _id: null,
      Time: { $min: "$Name.Time" },
      No: { $addToSet: "$Name.No" },
      Results: {
        $push: {
          k: "$_id",
          v: {
            Counters: "$Counters",
            TCR: {
              $reduce: {
                input: "$TCR",
                initialValue: [],
                in: {
                  $cond: [
                    {
                      $in: [
                        {
                          Name: "$$this.Name",
                          Result: "$$this.Result"
                        },
                        "$$value"
                      ]
                    },
                    "$$value",
                    {
                      $concatArrays: [
                        "$$value",
                        [
                          {
                            Name: "$$this.Name",
                            Result: "$$this.Result"
                          }
                        ]
                      ]
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  {
    $project: {
      _id: 0,
      Results: { $arrayToObject: "$Results" },
      Name: {
        Time: "$Time",
        No: {
          $reduce: {
            input: "$No",
            initialValue: "",
            in: {
              $concat: [
                "$$value",
                { $cond: [{ $eq: ["$$value", ""]}, "", "-"] },
                "$$this"
              ]
            }
          }
        }
      }
    }
  }
])

Playground

“。” (点)在“不”。字段无效,可能会导致 mongodb 查询操作出现问题,我建议不要使用“。” (点)作为字段名。

【讨论】:

  • no..还是不行,push也没有保留订单。
  • 您能否在您的问题中发布示例文档和预期结果。
  • 使用示例数据更新了问题
  • 根据您的查询,您的文档无效,您确定 Results 已经是数组吗?因为您已使用 x:{$objectToArray:"$Results"} 将其从对象转换为数组,因此不需要 $project 阶段。
  • 您现在可以检查一下吗
猜你喜欢
  • 2016-11-19
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-25
  • 1970-01-01
相关资源
最近更新 更多