【问题标题】:MongoDB remove elements depending on all other elements (Iterating)MongoDB 根据所有其他元素删除元素(迭代)
【发布时间】:2020-12-11 20:56:12
【问题描述】:

如果同一个对象具有相似的元素,我想从我的 MongoDB 对象中删除 ($reduce) 元素。我的对象:

  {
    "_id": "5eabf8b144345b36b00bfbaa",
    "ranktime": [
      {
        "pos": "15",
        "datum": "Mon May 01 2020 12:25:14 GMT+0200 (GMT+02:00)",
        "source": "SOURCE2"
      },
      {
        "pos": "10",
        "datum": "Fri May 05 2020 12:25:14 GMT+0200 (GMT+02:00)",
        "source": "SOURCE2"
      },
      {
        "pos": "15",
        "datum": "Mon May 01 2020 18:45:27 GMT+0200 (GMT+02:00)",
        "source": "SOURCE2"
      },
      {
        "pos": "20",
        "datum": "Fri May 05 2020 18:45:27 GMT+0200 (GMT+02:00)",
        "source": "SOURCE1"
      },
      {
        "pos": "10",
        "datum": "Fri May 05 2020 12:25:14 GMT+0200 (GMT+02:00)",
        "source": "SOURCE2"
      },
      {
        "pos": "15",
        "datum": "Mon May 01 2020 18:45:27 GMT+0200 (GMT+02:00)",
        "source": "SOURCE2"
      }
    ]
  }

因此,如果 ranktime.source == "SOURCE2" 并且日期与之前的对象相同,我想删除 ranktime 中的条目。实际上,我必须遍历 ranktime 的单个元素。这在 MongoDB 中可行吗?

预期结果是:

  {
    "_id": "5eabf8b144345b36b00bfbaa",
    "ranktime": [
      {
        "pos": "15",
        "datum": "Mon May 01 2020 12:25:14 GMT+0200 (GMT+02:00)",
        "source": "SOURCE2"
      },
      {
        "pos": "10",
        "datum": "Fri May 05 2020 12:25:14 GMT+0200 (GMT+02:00)",
        "source": "SOURCE2"
      },
      {
        "pos": "20",
        "datum": "Fri May 05 2020 18:45:27 GMT+0200 (GMT+02:00)",
        "source": "SOURCE1"
      }
    ]
  }

【问题讨论】:

标签: arrays mongodb mongoose mongodb-query aggregation-framework


【解决方案1】:

因此,根据您的示例,您要输出 ranktime 除非它是 SOURCE2 并且已将相同的日期添加到输出中(但仅为SOURCE2)。

您可以像以前一样使用$reduce,但您需要扫描可以使用$anyElementTrue 运算符实现的先前添加的元素,并且由于您的输出包含第三个元素,我假设重复日期仅在以下情况下才是停止条件为SORUCE2 添加了相同的日期,因此还需要$filter 来准备之前添加的SOURCE2s 集:

db.col.updateMany({}, [
    {
        $set: {
            ranktime: {
                $reduce: {
                    input: "$ranktime",
                    initialValue: [],
                    in: {
                        $cond: [ 
                            { 
                                $and: [ 
                                    { "$eq": [ "$$this.source", "SOURCE2" ] },
                                    {
                                        $anyElementTrue: {
                                            $map: {
                                                input: { $filter: { input: "$$value", as: "prev", cond: { $eq: { "$$prev.source", "SOURCE2" } } } }, // already added SOURCE2 elements
                                                as: "addedElement",
                                                in: { "$eq": [ { $substr: [ "$$addedElement.datum", 0, 15 ] }, { $substr: [ "$$this.datum", 0, 15 ] } ] }
                                            }                        
                                        }
                                    }
                                ]
                            },
                            "$$value", // skip current element ($$this) 
                            { $concatArrays: [ "$$value", [ "$$this" ] ] } // add current element to the output
                        ]
                    }
                }
            }
        }
    }
])

Mongo Playground

【讨论】:

  • 就是这样!非常感谢,mongodb 查询大师 :)
猜你喜欢
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-19
  • 2011-06-25
  • 1970-01-01
相关资源
最近更新 更多