如何避免 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 的对象,如果已预设则更新,如果不存在则插入。
在这种情况下,您可以尝试使用管道形式的更新,以及 filter
和 mergeObjects
运算符。
【讨论】:
以上是关于如何避免 mongodb 文档中的对象数组重复的主要内容,如果未能解决你的问题,请参考以下文章