MongoDB 根据所有其他元素删除元素(迭代)

Posted

技术标签:

【中文标题】MongoDB 根据所有其他元素删除元素(迭代)【英文标题】:MongoDB remove elements depending on all other elements (Iterating) 【发布时间】: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"
      
    ]
  

【问题讨论】:

这能回答你的问题吗? MongoDB remove elements depending on element before (Iterating) 重新表述您的要求:您只想输出 SOURCE2 的日期是唯一的还是跳过重复的日期? 【参考方案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 查询大师 :)

以上是关于MongoDB 根据所有其他元素删除元素(迭代)的主要内容,如果未能解决你的问题,请参考以下文章

Java 怎样删除一维数组中值为M的元素

集合遍历回顾--迭代器使用

vector 迭代 删除指定的元素

根据插入时间从std :: map中删除元素

iterable: 可迭代的

迭代时如何从通用列表中删除元素?