标签: azure-cosmosdb

匹配数百万人:kd 树还是局部敏感哈希?

我正在寻找一种高性能算法,根据以下数据结构按位置性别年龄匹配大量人员:

  • 经度(表示该人的位置)
  • 纬度(表示人的位置)
  • 性别(表示人的性别)
  • 出生日期(表示该人的出生日期)
  • LookForGender(表示该人正在寻找的性别)
  • LookForMinAge(表示该人正在寻找的最低年龄)
  • LookForMaxAge(表示该人正在寻找的最大年龄)
  • LookForRadius(表示该人正在寻找的最大距离)
  • 已处理(表示此人已经处理了哪些其他人)

对于任何人 P,算法应返回适用的候选人 C:

  • C 的性别必须相同 P.LookingForGender
  • P 的性别必须相同 C.LookingForGender
  • C 的出生日期必须介于 P.LookingForMinAge 和 P.LookingForMaxAge 之间
  • P 的出生日期必须介于 C.LookingForMinAge 和 C.LookingForMaxAge 之间
  • P 和 C 之间的纬度/经度距离必须小于或等于 P.LookingForRadius
  • P 和 C 之间的纬度/经度距离必须小于或等于 C.LookingForRadius
  • 加工后的P不得含有C

该算法应按距离(纬度/经度)顺序返回前 100 个候选 C。该算法应该针对搜索和更新进行优化,因为人们可能经常改变他们的位置。

我目前的想法是,kd 树可能比局部敏感哈希更适合这些需求,我应该朝这个方向发展。

您对我有什么建议?我应该寻找什么?您看到什么风险?

谢谢!

更新

  • 我是否愿意牺牲空间复杂度来获得更好的时间复杂度?是的,我更愿意牺牲空间复杂性。然而,我更喜欢有一个我真正理解并且可以维护的 O(log n) 解决方案,而不是一个我无法掌握的 O(1) 解决方案:)
  • 数据是否适合主存?不,不是的。数据将分布在分布式文档数据库(Azure Cosmos DB SQL API)的不同节点上。
  • 您想要精确的结果还是近似的结果?近似结果是可以的,但是应该精确过滤年龄/性别。
  • 在算法中添加了“已处理”,抱歉错过了!
  • 人们多久改变一次位置?用户每当启动应用程序并寻找候选人时都会改变他们的位置。因此,每日活跃用户每天会更改一次或多次位置。然而,位置变化可能很小,只有几公里。在 …

algorithm kdtree nearest-neighbor locality-sensitive-hash azure-cosmosdb

6
推荐指数
1
解决办法
1591
查看次数

在 Cosmos DB 中获取不同的值

我需要获得独特的价值。查询是SELECT DISTINCT c.Column1 FROM c. 此查询适用于页面中的distinct with,而不是整个集合。如果我再次运行上述相同的查询,它将返回带有延续令牌的下一组不同值。

我希望将不同的需求应用于整个集合,然后可以对结果进行分页。但它在页面中应用不同的 with 并返回带有继续标记的结果。我希望在不增加 RU/s 的情况下实现这一目标。

azure nosql azure-cosmosdb

6
推荐指数
1
解决办法
2万
查看次数

CosmosDB:查询 CosmosDB 时的 Linq 与 SqlQuerySpec 性能

我在查询 CosmosDB 特定文档时定期执行 LINQ 谓词。然而,今天我的 CosmosDB 中填满了 10 万多个文档。表演非常缓慢。由于 Azure 门户中的 SQL 查询明显更快,因此我尝试使用 SqlQuerySpec。瞧\xc3\xa1!它的工作速度快得多。

\n\n

谁能告诉我在 CosmosDB 中使用 Linq 谓词时到底发生了什么以及为什么它会减慢我的查询速度?

\n\n

下面的代码在我的获取文档的方法中使用。\n注意:在本例中,id 是分区键。

\n\n
        var collectionUri = UriFactory.CreateDocumentCollectionUri(CDBdatabase, CDBcollection);\n\n        var sqlStatement = new SqlQuerySpec\n        {\n            QueryText = "SELECT * FROM c where c.id = @id",\n            Parameters = new SqlParameterCollection()\n                {\n                          new SqlParameter("@id", consumerId),\n                },\n        };\n\n        IDocumentQuery<T> query = documentClient.CreateDocumentQuery<T>(\n            collectionUri,\n            sqlStatement,\n            .AsDocumentQuery();\n\n        List<ConsumerDetails> results = new List<ConsumerDetails>();\n        while (query.HasMoreResults)\n        {\n            results.AddRange(await query.ExecuteNextAsync<ConsumerDetails>());\n        }\n\n        return results.FirstOrDefault();\n
Run Code Online (Sandbox Code Playgroud)\n\n

相对而言,较慢的代码:

\n\n
        return documentClient.CreateDocumentQuery<ConsumerDetails>(\n …
Run Code Online (Sandbox Code Playgroud)

c# linq azure azure-cosmosdb

6
推荐指数
1
解决办法
1977
查看次数

Cosmos db 按“计算字段”排序

我正在尝试根据字符串状态选择数据。我想要的是状态“草稿”首先出现,所以我尝试了以下方法:

SELECT * 
FROM c 
ORDER BY c.status = "draft" ? 0:1
Run Code Online (Sandbox Code Playgroud)

我收到错误:

不支持 ORDER BY 子句。ORDER BY 项目表达式无法映射到文档路径

我检查了微软网站,我看到了这个:

ORDER BY 子句要求索引策略包含正在排序的字段的索引。Azure Cosmos DB 查询运行时支持根据属性名称排序,而不是根据计算属性排序。

我想这使得我想要通过查询做的事情变得不可能......我怎样才能实现这一目标?使用存储过程?

编辑

关于存储过程:实际上,我只是在考虑这个,这意味着,我需要在订购之前检索所有数据,这会很糟糕,因为我从数据库中获取最大 100 值...有什么办法可以做到这一点所以我不必先检索所有数据?谢谢

谢谢!

azure-cosmosdb

6
推荐指数
1
解决办法
3775
查看次数

如何编写 Azure Cosmos COUNT DISTINCT 查询

目标

返回 Cosmos 集合分区内特定文档字段的不同值的计数。

脚步

如果我在 Azure Cosmos 数据库上运行以下查询,

SELECT DISTINCT c.field
FROM c
WHERE c.field = 'abc' AND c.partitionKeyField = '123'
Run Code Online (Sandbox Code Playgroud)

我按预期得到一行,例如以下响应

[
    {
        "field": "abc"
    }
]

Run Code Online (Sandbox Code Playgroud)

但是,如果我随后运行以下查询以尝试通过以下查询计算响应中不同文档的数量

[
    {
        "field": "abc"
    }
]

Run Code Online (Sandbox Code Playgroud)

它返回

[
    6
]
Run Code Online (Sandbox Code Playgroud)

c.field这是设置为 的文档总数,"abc"而不是 的不同值的数量c.field

问题

请您帮助我理解为什么查询返回 的文档数量而不是不同值的数量c.field,以及是否有一个查询将返回 的不同值的数量c.field,即 1?

编辑-PS。我知道这是一个人为的示例,因为根据定义,唯一值的数量c.field始终为 1 - 我故意从实际情况简化了这一点。

distinct azure azure-cosmosdb azure-cosmosdb-sqlapi

6
推荐指数
1
解决办法
4052
查看次数

Azure Cosmos DB 使用基于角色的访问控制读取数据

我在 Azure 中有一个 CosmosDB,我想授予用户访问权限来读取各种集合内的数据。

我尝试给他们“读者”角色,这让他们知道存在 CosmosDB,并且他们可以看到一些元数据。但他们无法访问其中的数据

我为他们分配了“Cosmos DB 帐户阅读器”,这取得了更好的结果。

但在我看来,“读者”角色应该取代“Cosmos DB 帐户读者”角色。或者我在这里走错了路?我相信“读者”角色授予*所有读取权限。

编辑:使用Portal.azure.com
上内置的“数据资源管理器”似乎没有问题。

真正的问题是使用cosmos.azure.com和使用 ActiveDirectory 登录,没有让用户看到任何具有“Cosmos DB 帐户读取者”角色的内容。可能需要用户具有写入权限。

azure role-based-access-control azure-cosmosdb

6
推荐指数
1
解决办法
7733
查看次数

使用 Entity Framework Core 的 Azure Cosmos Db 429 重试策略

如果我的请求超过 RUS 的最大数量,要使用 Azure Cosmos API 客户端进行重试,我需要自己实施重试策略(例如使用 Polly)。
如果我将 EF Core 提供程序与 Cosmos DB 一起使用,EF 提供程序实现中是否会包含一些重试?如何配置呢?

azure azure-cosmosdb

6
推荐指数
0
解决办法
310
查看次数

处理多种类型的 Cosmos DB 容器的读取?

我想在单个 Cosmos DB 容器中存储几种不同的对象类型,因为它们都按逻辑分组,并且可以按时间戳一起读取,以避免额外的 HTTP 调用。

但是,Cosmos DB 客户端 API 似乎没有提供一种简单的方法来执行多种类型的读取。到目前为止,我找到的最好的解决方案是编写自己的 CosmosSerializer 和 JsonConverter,但这感觉很笨拙:https ://thomaslevesque.com/2019/10/15/handling-type-hierarchies-in-cosmos-db-part -2/

是否有一种更优雅的方法来将不同类型的项目读取到共享基类,以便我可以稍后转换它们,或者我是否必须接受打击?

谢谢!

azure-cosmosdb azure-cosmosdb-sqlapi

6
推荐指数
1
解决办法
2177
查看次数

何时应在 CosmosDB 中创建新容器?

我想在Azure CosmosDB上存储不同结构的数据。我知道容器可以存储不同类型的数据。在生产中,通过为它们分配不同的“类型”属性来区分它们。

当我观看最佳实践视频时:我注意到有两个容器(时间戳:17:47):CosmosDB 中的两个容器

第一个,users,只有一种数据类型,而第二个,posts,包含两种类型的内容:帖子和评论。

  1. 什么时候建议创建一个新容器而不是向已创建的容器添加不同类型的数据?
  2. 稍微解释一下这个问题:既然容器可以存储各种数据类型,为什么不将上面屏幕上的用户帖子评论放在一个容器中呢?

containers azure azure-cosmosdb

6
推荐指数
1
解决办法
1154
查看次数

在 Azure Cosmos DB 中维护分布式增量计数器

我对 cosmos DB 相当陌生,并试图了解azure cosmos DB SDK 为 Java 提供的用于修补文档的增量操作。我需要在容器中的文档之一中维护增量计数器。该文件看起来像这样——

{"counter": 1}
Run Code Online (Sandbox Code Playgroud)

现在,在我的应用程序中,每次发生操作时,我希望将此计数器的值增加 1。为此,我使用CosmosPatchOperations。我在这里添加一个增量,这样cosmosPatch.increment("/counter", 1)效果很好。

现在,该应用程序可以运行多个实例,所有实例都与 Cosmos 容器中的同一文档进行通信。所以App1和App2都可以同时触发增量。SDK 方法返回更新后的文档,我需要使用该更新后的值。

我的问题是,这里的 cosmos DB 是否采用某种锁定机制来确保两个补丁相继发生,并且在这种情况下,我在 App1 和 App2 中获得的更新值是什么(SDK 方法返回更新后的值)文档)。其中一个是 2 个,另一个是 3 个吗?

Couchbase 在集群级别支持这样的计数器,如此处所述它对我来说工作得很好,没有任何并发​​问题。我现在正在迁移到 cosmos Db,并一直在努力寻找如何实现这一目标。

更新1:

我决定测试一下。我在本地 Mac 中设置了 Cosmos 模拟器,并创建了一个 DB 和容器,并且 RU 会自动从 1 增加到 10K。然后在这个容器中我添加了一个像这样的文档 -

{
"id": "randomId",
"counter": 0
}
Run Code Online (Sandbox Code Playgroud)

在此之后,我创建了一个简单的 API,其职责只是在每次调用时将计数器加 1。然后我使用Locust多次调用这个 API 来模拟一个小型的类似负载的场景。最初,测试运行良好,每次调用都像预期的那样接收计数器(以增量方式)。在增加负载时,我看到一些错误,即RequestTimeOutException,状态代码为 408。其他请求仍然可以正常工作,并获得正确的计数器值。我不明白是什么导致了这里的 RequestTimeOut 异常。堆栈跟踪暗示与并发有关,但我无法理解它。这是堆栈跟踪 -

在此输入图像描述

更新 2: 更新 …

azure azure-cosmosdb

6
推荐指数
1
解决办法
1674
查看次数