我在MongoDB中有一个文档集合,看起来像。
{"_id": 1, "array": [{"id": 1, "content": "..."}, {"id": 2, "content": "..."}]}
{"_id": 2, "array": [{"id": 1, "content": "..."}, {"id": 2, "content": "..."}, {"a_id": 3, "content": "..."}]}
我想确保没有重复的文件。array.id
在每个文档中。因此,所提供的例子是可以的,但下面的例子就不行了。
{"_id": 1, "array": [{"id": 1, "content": "..."}, {"id": 1, "content": "..."}]}
我的问题是如何做到这一点(最好是在以下情况下) PyMongo
).
编辑
我尝试的是下面的代码,我认为可以创建键上。(_id, array.id)
但如果你运行它就不会发生这种情况。
from pymongo import MongoClient, ASCENDING
client = MongoClient(host="localhost", port=27017)
database = client["test_db"]
collection = database["test_collection"]
collection.drop()
collection.create_index(keys=[("_id", ASCENDING),
("array.id", ASCENDING)],
unique=True,
name="new_key")
document = {"array": [{"id": 1}, {"id": 2}]}
collection.insert_one(document)
collection.find_one_and_update({"_id": document["_id"]},
{"$push": {"array": {"id": 1}}})
updated_document = collection.find_one({"_id": document["_id"]})
print(updated_document)
它的输出(注意,有两个对象带有 id = 1
在 array
). 我希望得到一个异常。
{'_id': ObjectId('5eb51270d6d70fbba739e3b2'), 'array': [{'id': 1}, {'id': 2}, {'id': 1}]}
所以,如果我理解正确的话,没有办法设置索引(或一些条件)来强制文档的唯一性,对吗?(除了在创建文档或插入文档时明确地检查这个之外。)
是的。请看下面两个关于在嵌入文档的数组字段上使用唯一索引的场景。
唯一的多键索引 (数组内嵌入文档字段的索引)。
对于唯一的索引,唯一的约束适用于集合中的不同文档,而不是在单个文档中。
因为唯一约束适用于不同的文档,所以对于唯一的多键索引,只要该文档的索引键值不与另一个文档的索引键值重复,该文档的数组元素可能会导致重复的索引键值。
第一种情况。
db.arrays.createIndex( { _id: 1, "array.id": 1}, { unique: true } )
db.arrays.insertOne( { "_id": 1, "array": [ { "id": 1, "content": "11"}, { "id": 2, "content": "22"} ] } )
db.arrays.insertOne( { "_id": 2, "array": [ { "id": 1, "content": "1100"}, { "id": 5, "content": "55"} ] } )
db.arrays.insertOne( {"_id": 3, "array": [ {"id": 3, "content": "33"}, {"id": 3, "content": "3300"} ] } )
所有三个文档都被插入,没有任何错误。
根据关于 獨特的多鍵索引上文中,该文件有 _id : 3
在数组内有两个内嵌的文件,它们具有相同的 "array.id"
价值。3
.
同时,在复合索引的两个键上也强制执行唯一性。{ _id: 1, "array.id": 1}
而且有重复的 "array.id"
的值,也是跨文件的值( _id
价值观 1
和 2
).
第二种情况。
db.arrays2.createIndex( { "array.id": 1 }, { unique: true } )
db.arrays2.insertOne( { "_id": 3, "array": [ { "id": 3, "content": "33" }, { "id": 3, "content": "330"} ] } )
db.arrays2.insertOne( { "_id": 4, "array": [ { "id": 3, "content": "331" }, { "id": 30, "content": "3300" } ] } )
第一份文件有: _id : 3
被成功插入。第二个有一个错误。"errmsg" : "E11000 duplicate key error collection: test.arrays2 index: array.id_1 dup key: { array.id: 3.0 } "
. 这种行为是根据注释中的预期 獨特的多鍵索引.