【问题标题】:Azure CosmosDB Contains method does not workingAzure CosmosDB Contains 方法不起作用
【发布时间】:2018-11-05 19:52:22
【问题描述】:

我不确定,但我认为我在 Azure Cosmos DB 中发现了一个错误。这是我的情况。我有以下 JSON

{
    "id": "token",
    "User": {
        "UserToken": "token",
        "Email": "email@email.com"
    },
    "_ts": 1521728825
}

我使用 LINQ 编写了以下查询:

await _dbClient.Where<UserDocument>(_collectionUri,feedOptions,  
        d => d.User.UserToken == searchString
             || d.User.Email.Contains(searchString))                        
    .OrderByDescending(d => d.Timestamp)
    .AsDocumentQuery().ToListAsync())

当我用searchString=="token" 运行它时,它会返回一个空列表,所以我决定修改查询:

await _dbClient.Where<UserDocument>(_collectionUri,feedOptions,  
        d => d.User.UserToken == searchString)                        
    .OrderByDescending(d => d.Timestamp)
    .AsDocumentQuery().ToListAsync())

神奇地它开始工作了。有人可以告诉我我做错了什么吗?或者 CosmosDB 中的 CONTAINS 方法可能存在问题??

【问题讨论】:

  • 有趣的事实是,当我将 order by 子句添加到查询中时,我始终得到零结果。
  • UserToken 是否已编入索引?如果是这样,您的索引是一致的还是惰性的?

标签: c# linq azure asp.net-core azure-cosmosdb


【解决方案1】:

这不是错误。这与您收藏的索引政策有关。

我不知道您当前的索引策略是什么样的,但是当在字符串上完全匹配有效而部分匹配无效时,可以肯定地说您正在为您的字符串使用 Hash 索引.

使用散列时,只有相等检查才会返回值。您需要将字符串索引更改为 Range 和精度 -1 以部分匹配字符串。

您可以在数据浏览器的 Scale &amp; Settings 部分下找到您的索引设置。

如果您的索引策略如下所示:

然后改成这样:

应该可以。

但是,您可以进一步限制这一点,仅将/User/Email/? 索引为Range,并将其余部分保留为哈希。

您还可以通过提供一个将值EnableScanInQuery 设置为trueFeedOptions 对象来覆盖此行为。但是我的结果好坏参半,所以我会更改索引。

我强烈建议您查看索引文档here。还有一个很棒的视频解释了更多关于它的信息。

【讨论】:

  • 你说得对。正如你提到的,我的索引策略无效,OrderBy 破坏了我的查询
  • 是的,在系统定义的_ts 字段上排序很棘手。 OrderBy 也不适用于 Hash 字段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-10-02
  • 2018-03-22
  • 1970-01-01
  • 2021-01-25
  • 2017-10-25
  • 2012-04-01
  • 1970-01-01
相关资源
最近更新 更多