如何避免 mongodb 文档中的对象数组重复

Posted

技术标签:

【中文标题】如何避免 mongodb 文档中的对象数组重复【英文标题】:How to avoid duplication in array of objects in a mongodb document 【发布时间】:2021-12-19 05:16:07 【问题描述】:

这是文档示例:


    "_id": "658016",
    "playerName": "Kuldeep Singh",
    "tournamentId": "197831",
    "score": [
        
            "_id": "1611380",
            "runsScored": 21,
            "ballFaced": 10,
            "fours": 3,
            "sixes": 1,
            "strikeRate": 210,
            "oversBowled": 3,
            "runsConceded": 34,
            "economyRate": 11.33,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "c Mayank b Nitin Gudle -(reddy)",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1602721",
            "runsScored": 21,
            "ballFaced": 14,
            "fours": 1,
            "sixes": 1,
            "strikeRate": 150,
            "oversBowled": 3,
            "runsConceded": 28,
            "economyRate": 9.33,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "not out",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1536540",
            "runsScored": 1,
            "ballFaced": 3,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 33.33,
            "oversBowled": 2,
            "runsConceded": 7,
            "economyRate": 3.5,
            "wickets": 3,
            "maiden": 0,
            "howToOut": "b Lalit",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1536483",
            "runsScored": 0,
            "ballFaced": 0,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 0,
            "oversBowled": 0,
            "runsConceded": 0,
            "economyRate": 0,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "-",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1501201",
            "runsScored": 12,
            "ballFaced": 5,
            "fours": 1,
            "sixes": 1,
            "strikeRate": 240,
            "oversBowled": 2,
            "runsConceded": 28,
            "economyRate": 14,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "c Rahul Mogri b Harshal Tupe",
            "catches": [
                "Chetan Tupe",
                "Kaustubh Tupe"
            ],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1501195",
            "runsScored": 74,
            "ballFaced": 27,
            "fours": 5,
            "sixes": 7,
            "strikeRate": 274.07,
            "oversBowled": 3,
            "runsConceded": 44,
            "economyRate": 14.67,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "not out",
            "catches": [
                "Ashish Thantharatey"
            ],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1461428",
            "runsScored": 8,
            "ballFaced": 4,
            "fours": 0,
            "sixes": 1,
            "strikeRate": 200,
            "oversBowled": 3,
            "runsConceded": 29,
            "economyRate": 9.67,
            "wickets": 2,
            "maiden": 0,
            "howToOut": "run out Mayank / Sahil Raheja",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1461413",
            "runsScored": 23,
            "ballFaced": 12,
            "fours": 0,
            "sixes": 3,
            "strikeRate": 191.67,
            "oversBowled": 2,
            "runsConceded": 18,
            "economyRate": 9,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "c Sumit Gandhi b Arun Stambhampelli",
            "catches": [
                "Arun Stambhampelli (c)"
            ],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1451183",
            "runsScored": 16,
            "ballFaced": 6,
            "fours": 2,
            "sixes": 1,
            "strikeRate": 266.67,
            "oversBowled": 2,
            "runsConceded": 11,
            "economyRate": 5.5,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "c Syed Jamaal Nasir b Aman Deep",
            "catches": [
                "Mohan Slathia (c)"
            ],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1451132",
            "runsScored": 26,
            "ballFaced": 10,
            "fours": 1,
            "sixes": 3,
            "strikeRate": 260,
            "oversBowled": 3,
            "runsConceded": 18,
            "economyRate": 6,
            "wickets": 3,
            "maiden": 0,
            "howToOut": "c Javed b Ram Lomte",
            "catches": [
                "Saheb Desai"
            ],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1392788",
            "runsScored": 13,
            "ballFaced": 6,
            "fours": 2,
            "sixes": 0,
            "strikeRate": 216.67,
            "oversBowled": 3,
            "runsConceded": 30,
            "economyRate": 10,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "not out",
            "catches": [
                "Sachin Patil"
            ],
            "stumping": [],
            "runout": [],
            "participatedRunout": [
                "Pankaj Rastogi"
            ]
        ,
        
            "_id": "1611380",
            "runsScored": 0,
            "ballFaced": 0,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 0,
            "oversBowled": 0,
            "runsConceded": 0,
            "economyRate": 0,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "-",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1602721",
            "runsScored": 0,
            "ballFaced": 0,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 0,
            "oversBowled": 0,
            "runsConceded": 0,
            "economyRate": 0,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "-",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1536540",
            "runsScored": 0,
            "ballFaced": 0,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 0,
            "oversBowled": 0,
            "runsConceded": 0,
            "economyRate": 0,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "-",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1501201",
            "runsScored": 0,
            "ballFaced": 0,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 0,
            "oversBowled": 0,
            "runsConceded": 0,
            "economyRate": 0,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "-",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1501195",
            "runsScored": 0,
            "ballFaced": 0,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 0,
            "oversBowled": 0,
            "runsConceded": 0,
            "economyRate": 0,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "-",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1461428",
            "runsScored": 0,
            "ballFaced": 0,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 0,
            "oversBowled": 0,
            "runsConceded": 0,
            "economyRate": 0,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "-",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1461413",
            "runsScored": 0,
            "ballFaced": 0,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 0,
            "oversBowled": 0,
            "runsConceded": 0,
            "economyRate": 0,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "-",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1451183",
            "runsScored": 0,
            "ballFaced": 0,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 0,
            "oversBowled": 0,
            "runsConceded": 0,
            "economyRate": 0,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "-",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1451132",
            "runsScored": 0,
            "ballFaced": 0,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 0,
            "oversBowled": 0,
            "runsConceded": 0,
            "economyRate": 0,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "-",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        ,
        
            "_id": "1392788",
            "runsScored": 0,
            "ballFaced": 0,
            "fours": 0,
            "sixes": 0,
            "strikeRate": 0,
            "oversBowled": 0,
            "runsConceded": 0,
            "economyRate": 0,
            "wickets": 0,
            "maiden": 0,
            "howToOut": "-",
            "catches": [],
            "stumping": [],
            "runout": [],
            "participatedRunout": []
        
    ],
    "__v": 0

注意:在本文档内的 score 数组中,索引 10 之后有重复的对象。

使用以下代码初始更新文档(在此之前,分数数组为空):

await Scorecard.findOneAndUpdate(
         _id: fielder.player_id, ,
        
          $addToSet: 
            "score": 
              _id: matchID
            
          
        
      );

稍后在代码中,分数数组中的对象再次更新以更改初始未更改字段的默认值(在猫鼬模式中设置)。

但是,问题是当上面引用的代码在一段时间后再次运行时,它会复制数组中的所有对象。我知道,还有其他类似的问题,但我是 mongodb 的初学者,无法制作复杂的聚合管道。非常感谢任何帮助。

【问题讨论】:

我们也可以知道您提供的参数的内容吗?即matchID 我应该与您分享有关 matchID 的哪些信息 @ray 对于提到的文档,它的值为658016。 @ray matchID 对于所有对象都是唯一的,但是重复会导致具有特定 ID 的对象出现两次或三次,具体取决于多少次,我允许函数运行 我不确定我们是否可以复制您的问题。在this trial in playground 中,它应该只能插入一个只有1 个字段_id 的对象。在我看来,可能需要提供一些其他内容来复制您的问题。 【参考方案1】:

$addToSet 运算符仅在数组不存在的情况下添加一个元素。

该数组中的每个元素都是一个对象。对象按照https://docs.mongodb.com/manual/reference/bson-type-comparison-order/#objects 的 mongodb 文档中的描述进行比较 基本上,如果两个对象具有完全相同的字段、以完全相同的顺序、每个对象具有完全相同的值,则它们是相等的。换句话说,如果它们不相同,它们就不相等。

我在问题的数组中看不到任何重复项。 _id 字段有一些具有相同值,但它们包含其他几个不同的字段,因此它们不是重复的。

如果您需要更新数组中某个对象的值,还有其他几个关于修改嵌套文档的问题。

我怀疑您要做的是检测数组中是否已存在具有该 ID 的对象,如果已预设则更新,如果不存在则插入。 在这种情况下,您可以尝试使用管道形式的更新,以及 filtermergeObjects 运算符。

【讨论】:

以上是关于如何避免 mongodb 文档中的对象数组重复的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB 如何查询和修改内嵌文档

如何在mongodb中查找各种数组的“作者”字段?

如何计算mongodb中子对象(同一文档)的数量[重复]

将嵌套的 mongoDB 文档转换为平面 pandas DataFrame(对象数组中的对象数组)

如何使用MongoDB过滤子文档中的数组[重复]

如何使MongoDB的列成为SQL Server中发生的主键,避免重复记录?