E11000在唯一化合物索引中插入具有现有第一个元素的数组时出现重复键错误

时间:2019-08-20 08:29:27

标签: arrays node.js mongodb

我有一个集合:test,并且我有一个由此创建的唯一化合物索引: db.collection('test').createIndex({ path: 1, price: 1, type: 1 }, { unique: true });

路径是一个数组,价格和类型是字符串

并且我正在尝试插入文档:

db.test.insertOne({ path: [ 'Some', 'Thing' ], price: '1.00', type: '' })

这有效,我可以在收藏夹中看到该文档,但是当我尝试插入另一个文档时:

db.test.insertOne({ path: [ 'Some', 'Thing', 'Else' ], price: '1.00', type: '' })

我收到此错误:

2019-08-20T11:04:10.560+0300 E QUERY    [js] WriteError: E11000 duplicate key error collection: api.test index: path_1_price_1_type_1 dup key: { : "Some", : "1.00", : "" } :
WriteError({
        "index" : 0,
        "code" : 11000,
        "errmsg" : "E11000 duplicate key error collection: api.test index: path_1_price_1_type_1 dup key: { : \"Some\", : \"1.00\", : \"\" }",
        "op" : {
                "_id" : ObjectId("5d5ba97a19d534f6cc2fc050"),
                "path" : [
                        "Some",
                        "Thing"
                ],
                "price" : "1.00",
                "type" : ""
        }
})
WriteError@src/mongo/shell/bulk_api.js:461:48
Bulk/mergeBatchResults@src/mongo/shell/bulk_api.js:841:49
Bulk/executeBatch@src/mongo/shell/bulk_api.js:906:13
Bulk/this.execute@src/mongo/shell/bulk_api.js:1150:21
DBCollection.prototype.insertOne@src/mongo/shell/crud_api.js:252:9
@(shell):1:1

我尝试将updateOne与upsert:true一起使用,但出现相同的错误 即使第一个字段值是一个数组,在尝试插入时它似乎也只将第一个元素变成红色,而实际上我在尝试插入数组时却给了我dup key: { : "Some", : "1.00", : "" } ...

这是我在控制台中运行的完整代码:

db.collection('test').createIndex({ path: 1, price: 1, type: 1 }, { unique: true });
db.test.insertOne({ path: [ 'Some', 'Thing' ], price: '1.00', type: '' })
db.test.insertOne({ path: [ 'Some', 'Thing', 'Else' ], price: '1.00', type: '' })

路径可以不同,所以如果我尝试插入此路径:

db.test.insertOne({ path: [ 'Some', 'Thing' ], price: '1.00', type: '' })
db.test.insertOne({ path: [ 'Bla', 'Bla' ], price: '1.00', type: '' })

有效

但是如果存在数组元素之一:

db.test.insertOne({ path: [ 'Bla', 'Thing' ], price: '1.00', type: '' })

我得到那个错误

有人可以帮助我解决此问题吗?我需要路径,价格和类型是唯一的,但我只需要路径是唯一的作为数组,而不是像数组中任何元素一样唯一

谢谢

1 个答案:

答案 0 :(得分:1)

在MongoDB中,索引数组称为多键索引。在这种情况下,MongoDB会分别索引数组的每个值。这就是为什么您得到重复的密钥。

一种解决方法是将数组“隐藏”在子文档中,以防止对数组进行实际索引。

例如:

{
  "path": {
     "sub_doc" : [ "Bla", "Things" ]
  }
}

请注意,在这种情况下,数组的元素不再被索引。这意味着您将无法通过索引直接在"Bla""Things"上进行请求。仅完整对象sub_doc