我的Azure Cosmos数据库中有以下文档:
{
"id": "token",
"User": {
"UserToken": "token",
"Email": "test@email.com"
},
"_ts": 1541493290
}
当我运行以下查询时:
SELECT * FROM root
WHERE ((root["User"]["UserToken"] = "token")
OR CONTAINS(root["User"]["Email"], "token"))
ORDER BY root["_ts"] DESC
什么都不返回。但是当我改变它的时候。例如,将Email
转换为email
:
SELECT * FROM root
WHERE ((root["User"]["UserToken"] = "token")
OR CONTAINS(root["User"]["email"], "token"))
ORDER BY root["_ts"] DESC
找到结果。此外,当我删除ORDER BY
子句时,查询也会返回一个结果。所以查询就像下面的
SELECT * FROM root
WHERE ((root["User"]["UserToken"] = "token")
OR CONTAINS(root["User"]["Email"], "token"))
此外,当我编辑文档时(如打开文档,添加空行并保存),背景中发生了一些魔术,并找到了文档。对于相当“新”的文档(少于1-3个月),我无需使用“魔术”技巧就可以进行搜索。
索引的定义是:
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*",
"indexes": [
{
"kind": "Range",
"dataType": "Number",
"precision": -1
},
{
"kind": "Hash",
"dataType": "String",
"precision": 3
}
]
}
],
"excludedPaths": []
}
我做错了什么?
更新答案不是一个完整的解释,但很有帮助。完整的解释在我的博客(https://stapp.space/ridiculous-bug-in-azure-cosmos-db/)
中答案 0 :(得分:1)
CONTAINS(root["User"]["Email"], "token")
,则 Hash
将不起作用。它们必须是Range
,精度为-1
。哈希仅适用于相等性检查。
这就是小写字母起作用的原因。因为它找不到属性,而只是忽略它,所以退回到相等检查。第一个找到它,发现它没有索引为Range,只是返回失败。
更改对此的索引将起作用:
{
"indexingMode": "consistent",
"automatic": true,
"includedPaths": [
{
"path": "/*",
"indexes": [
{
"kind": "Range",
"dataType": "Number",
"precision": -1
},
{
"kind": "Range",
"dataType": "String",
"precision": -1
}
]
}
],
"excludedPaths": []
}
另一方面,_ts
字段不是基于创建进行排序的最佳方法。这是一个以秒为单位的unix时间戳,因此在同一秒内创建的任何文档都将无法正确排序。