首页 > 解决方案 > Azure Cosmos DB 中的奇怪查询结果

问题描述

我的 Azure Cosmos DB 中有以下文档:

{
    "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 

什么都没有返回。但是当我稍微改变一下。例如通过转换Emailemail

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/

标签: azureazure-cosmosdb

解决方案


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 时间戳,因此在同一秒内创建的任何文档都不会正确排序。


推荐阅读