不同“id”字段的唯一性

问题描述 投票:0回答:1

我需要强制 Mongo 数据库集合中文档的唯一性。

我的文档有一个“id”字段和一个“name”字段,以及其他几个字段。 “id”字段不是唯一的。

我的要求是“名称”在不同的“id”值中应该是唯一的。但是,可以有多个具有相同“id”和相同“名称”的文档。 (同一个“id”中可以有多个“name”)。

例如:
允许使用以下文件(相同 ID、相同/不同名称):

{ "id" : "1", "name": "Alice", ...}

{ "id" : "1", "name": "Bob", ...}

{ "id" : "1", "name": "Alice", ...}

但是不允许以下内容(相同名称,不同 ID):

{ "id" : "1", "name": "Alice", ...}

{ "id" : "2", "name": "Alice", ...}

是否有可能在数据库本身而不是应用程序逻辑中强制执行此操作?

mongodb azure-cosmosdb
1个回答
0
投票

我认为仅通过数据库手段无法用现有数据“执行”该规则。如果您有违反规则的数据,您可能需要进行一次性清理。但是,对于新插入的文档,您可以在聚合中执行以下操作并将它们合并到集合中。

  1. $unionWith
    您要插入的新文档(将它们放入
    $documents
  2. $setWindowFields
    计算分区
    $denseRank
    内的
    name
    并按
    id
    的顺序
    • 对于情况1,如果他们有不同的名字,他们的排名都是:1
    • 对于情况2,如果他们有相同的名字和相同的id,他们的排名都是:1
    • 对于情况3,如果它们具有相同的名称但不同的id,则新文档的排名将> 1
  3. $match
    仅选择排名为 1 的文档
  4. (化妆品)
    $unset
    排名字段
  5. $merge
    进入收藏
db.collection.aggregate([
  {
    "$unionWith": {
      "coll": "collection",
      "pipeline": [
        {
          "$documents": [
            // documents to be inserted here
            {
              "id": "1",
              "name": "Alice"
            }
          ]
        }
      ]
    }
  },
  {
    "$setWindowFields": {
      "partitionBy": "$name",
      "sortBy": {
        "id": 1
      },
      "output": {
        "idRankInName": {
          "$denseRank": {}
        }
      }
    }
  },
  {
    "$match": {
      "idRankInName": 1
    }
  },
  {
    "$unset": "idRankInName"
  },
  {
    "$merge": {
      "into": "collection"
    }
  }
])

案例 1 和案例 2 的 Mongo Playground
案例 3 的 Mongo Playground

© www.soinside.com 2019 - 2024. All rights reserved.