在mongodb中,如何为一个文档列表创建一个唯一的索引?

wbrvyc0a  于 2022-12-03  发布在  Go
关注(0)|答案(1)|浏览(160)

我有一系列这样的文档:

[
  {
    _id: ObjectId("63845afd1f4ec22ab0d11db9"),
    ticker: 'ABCD',
    aggregates: [
      { date: '2022-05-20' },
      { date: '2022-05-20' },
      { date: '2022-05-20' }
    ]
  }
]

如何在www.example.com上创建唯一索引aggregates.date,以便用户不会将重复的日期推入数组聚合。
我现有的汇总如下:

db.aggregates_1_day.getIndexes()
[
  { v: 2, key: { _id: 1 }, name: '_id_' },
  { v: 2, key: { ticker: 1 }, name: 'ticker_1', unique: true },
  {
    v: 2,
    key: { 'aggregates.date': 1 },
    name: 'aggregates.date_1',
    unique: true
  }
]
polhcujo

polhcujo1#

唯一索引可确保文档之间没有重复项,但不强制同一集合文档数组中对象唯一性

但您在这里几乎没有其他选择:

1.不要使用$push,而要使用$addToSet在对象的聚合数组中添加唯一对象:

db.collection.update({},
    {
    "$addToSet": {
    "aggregates": {
     date: "2022-05-20"
      }
     }
   })

注意:$addToSet只确保没有重复的项目添加到集合中,并且不影响现有的重复元素。
Playground

2.您可以配置架构validation

> db.runCommand({collMod:"aggregates_1_day", validator: {$expr:{$eq:[{$size:"$aggregates.date"},{$size:{$setUnion:"$aggregates.date"}}]}}})
   > db.aggregates_1_day.insert({aggregates:[{date:1}]}) /* success */
   > db.aggregates_1_day.update({},{ '$push' : { 'aggregates':{date:1}}})
   WriteResult({
    "nMatched" : 0,
    "nUpserted" : 0,
    "nModified" : 0,
    "writeError" : {
        "code" : 121,
        "errmsg" : "Document failed validation"
    }
   })
   >

mongoDB票证中的更多详细信息
注意:在这种方法中,您需要提前清除重复项,否则验证将根本不允许$push新对象。
如果您不喜欢它,可以使用以下命令删除验证:

db.runCommand({
     collMod: "aggregates_1_day",
     validator: {},
     validationLevel: "off"
   })

3.您可以使用更新/汇总,如下所示:

db.collection.update({},
   [
   {
    $set: {
    aggregates: {
     $cond: [
       {
        $in: [
          "2022-02-02",
          "$aggregates.date"
        ]
       },
       "$aggregates",
      {
        $concatArrays: [
          "$aggregates",
          [
            {
              date: "2022-02-02"
            }
          ]
        ]
       }
      ]
     }
    }
   }
   ])

解释道:
1.仅当对象数组中不存在对象时,才将对象添加到数组中。
Playground3

相关问题