MongoDB 文件路径作为唯一索引

MongoDB file path as unique index

我应该如何整理我的文档集:

{ 
 "path" : "\192.168.77.1\user.wav", // unique text index
 "sex" : "male", "age" : 28 // some fields 
}

我在 Python (pymongo) 中使用这个方案:

client = MongoClient(self.addr)
db = self.client['some']
db.files.ensure_index([('path', TEXT)], unique=True)

data = [
    {"path": r'\192.168.77.5.wav', "base": "CAGS2"},
    {"path": r'\192.168.77.5.wav', "base": "CAGS2"}
]
sid = self.db.files.insert(data)

但是出现错误:

pymongo.errors.DuplicateKeyError: insertDocument :: 
caused by :: 11000 E11000 duplicate key error index: 
some.files.$path_text  dup key: { : "168", : 0.75 }

如果我删除路径键中的所有点 ('.'),一切正常。怎么了?

您是否对输入字段中的所有文本进行了转义以确保它是有效的 JSON 文档?

这是一份有效的json文件

{
    "path": "\"\\192.168.77.1\user\1.wav\"",
    "sex": "male",
    "age": 28
}

您已将文本索引设置为唯一 - 集合中是否已有路径值为 "\192.168.77.1\user.wav" 的文档?

Mongo 也可能将路径中的标点符号视为分隔符,这可能会影响其存储方式。 MongoDB $search field

为什么要创建唯一的文本索引?就此而言,为什么 MongoDB 让你这么做?创建文本索引时,输入字段值被标记化:

"the brown fox jumps" -> ["the", "brown", "fox", "jumps"]

标记是词干化的,这意味着它们(以特定于语言的方式)被简化为不同的形式以支持自然语言匹配,例如 "loves" 与 "love" 和 "loving" 与"love"。诸如 "the" 之类的停用词是对匹配危害大于帮助的常用词,已被丢弃。

["the", "brown", "fox", "jumps"] -> ["brown", "fox", "jump"]

文档的索引条目是原始字段值的词干标记,其分数是根据术语在值字符串中的重要性计算得出的。因此,当您对这些值设置唯一索引时,您可以确保不会有两个文档的术语源于同一事物并具有相同的分数。这几乎不是你想要的,因为很难说它会拒绝什么。这是一个例子:

> db.test.drop()
> db.test.ensureIndex({ "t" : "text" }, { "unique" : true })
> db.test.insert({ "t" : "ducks are quacking" })
WriteResult({ "nInserted" : 1 })
> db.test.insert({ "t" : "did you just quack?" })
WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 11000,
        "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: test.test.$a_text  dup key: { : \"quack\", : 0.75 }"
    }
})
> db.test.insert({ "t" : "though I walk through the valley of the shadow of death, I will fear no quack" })
WriteResult({ "nInserted" : 1 })

词干词 "quack" 将来自所有三个文档,但在前两个文档中它获得 0.75 的分数,因此第二个插入被唯一约束拒绝。它在第三个文档中获得 0.5625 的分数。

您实际上想通过路径上的索引实现什么?唯一的文本索引不是您想要的。

我为 'path' 创建了一个带有 TEXT 索引的方案,并将其保存在数据库中。 之后我尝试将 TEXT 更改为 ASCENDING/DESCENDING 但没有任何效果,因为我没有进行索引重置(或删除并再次创建整个数据库)。

因此,正如 wdberkeley 在下面写道:当您创建文本索引时,输入字段值被标记化:

"the brown fox jumps" -> ["the", "brown", "fox", "jumps"]

TEXT 索引不是文件名的解决方案。请改用 ASCENDING/DESCENDING。