简介
大家好,我是 Zein Wen,是 Qdrant 2023 年 Google 编程之夏的参与者。我与一位出色的导师 Arnaud Gourlay 合作,增强了 Qdrant 地理多边形过滤器。这项新功能允许用户使用多边形优化他们的查询结果。作为地理过滤器家族中半径和矩形过滤器的最新成员,这项增强功能有望在查询地理数据方面提供更大的灵活性,开启了有趣的新的用例。
项目概述

地理过滤器的一个用例(https://traveltime.com/blog/map-postcode-data-catchment-area)
由于 Qdrant 是一个强大的查询向量数据库,它为机器学习驱动的应用程序(如推荐)提供了巨大的潜力。然而,仅凭向量查询的范围可能无法始终满足用户的需求。考虑这样一个场景:您正在寻找餐厅推荐;这不仅仅是餐厅列表,而是您所在社区内的餐厅。这就是地理过滤器的用武之地,它通过加入额外的过滤条件来增强查询。到目前为止,Qdrant 的地理过滤选项仅限于圆形和矩形,这可能与现实世界中发现的各种边界不符。这种情况正是导致用户提出功能请求的原因,我们认为这是一个很好的功能,因为它为地理相关查询引入了更大的能力。
技术挑战
1. 地理几何计算

地理空间基本概念
在内部,地理过滤器不会从测试每个单独的地理位置开始,因为这将是计算昂贵的。相反,我们创建一个地理哈希层,将世界划分为矩形。当为 Qdrant 条目创建空间索引时,它会将该条目分配给其位置的地理哈希。
在查询期间,我们首先识别所有满足过滤条件的潜在地理哈希,然后检查这些哈希内的位置候选项。完成此搜索涉及两个关键的几何计算
- 确定多边形是否与矩形相交
- 确定点是否位于多边形内。

几何计算测试
虽然我们有一个地理 crate(一个 Rust 库)提供这些计算的 API,但我们深入研究以了解底层算法并验证其准确性。这导致我们进行了广泛的测试和可视化以确定正确性。除了评估当前的 crate,我们还发现有多种算法可用于这些计算。我们投入时间探索不同的方法,例如缠绕数和射线投射,以掌握它们的区别,并为未来的改进铺平道路。
通过这个过程,我喜欢磨练自己快速掌握不熟悉概念的能力。此外,我需要开发分析策略来剖析它们并从中得出有意义的结论。这段经历在扩展我的问题解决工具包方面是无价的。
2. Proto 和 JSON 格式设计
我们投入了大量精力来设计此新功能的 ProtoBuf 和 JSON 接口。这个组件直接暴露给用户,需要一个一致且用户友好的接口,这反过来有助于推动积极的用户体验并减少未来的代码修改。
最初,我们曾考虑将我们的接口与 GeoJSON 规范对齐,因为它作为许多地理相关 API 的标准而闻名。然而,我们很快意识到 GeoJSON 定义几何图形的方式与我们当前的 JSON 和 ProtoBuf 坐标定义(用于我们的点半径和矩形过滤器)显著不同。因此,我们优先考虑 API 级别的一致性和用户体验,选择将新的多边形定义与我们所有现有定义对齐。
此外,我们计划除了多边形之外,还要开发一个单独的多多边形过滤器。然而,经过仔细考虑,我们认识到,对于我们的用例,多边形过滤器可以实现与多多边形过滤器相同的结果。这种关系反映了我们目前处理多个圆形或矩形的方式。因此,我们认为多多边形过滤器是多余的,并且会给 API 引入不必要的复杂性。
这项工作向我展示了在实际解决方案中寻找平衡的挑战,即在遵循既定标准和优先考虑用户体验之间取得平衡。这也是理解专注于开发用户真正需要的东西而不分散我们精力的智慧的关键。
成果
1. 深入研究的能力 驾驭不熟悉的代码库、概念、API 和技术是开发人员面临的普遍挑战。参与 GSoC 就像我从游泳池的安全区直接进入广阔的海洋。在此过渡期间,我的导师的支持是无价的。他给了我很多机会独立深入研究我以前从未探索过的领域。我已经不再害怕未知的技术领域,无论是特定领域中不熟悉的代码、技术还是概念。我对学习它们并逐步使用它们来创造我所设想的东西充满了信心。
2. 始终将用户放在心上 我学到的另一个重要教训是考虑用户体验及其特定用例的重要性。虽然开发有时可能涉及迭代过程,但直接影响用户的每个方面都必须以同理心来对待和执行。忽视这一点不仅会导致功能错误,还会因为不一致和混乱而侵蚀用户的信任,从而导致他们不再使用我的工作。
3. 大声说出来并有效沟通 最后,在开发过程中,遇到不同意见是很常见的。保持对他人想法的开放性至关重要,同时也要有清晰表达自己观点的决心。这有助于富有成效的讨论,并最终提高开发过程的质量。
总结
被选为 2023 年 Google 编程之夏的参与者,并与 Arnaud 和其他 Qdrant 工程师以及所有其他社区成员合作,是真正的荣幸。我非常感谢那些投入时间和精力审查我的代码、参与有关替代方案和设计选择的讨论并在需要时提供帮助的人。通过这些互动,我亲身体验了开源的精髓以及鼓励协作的文化。这次经历不仅让我第一次为真实世界的产品编写 Rust 代码,还为我打开了令人惊叹的开源世界的大门。
毫无疑问,我渴望继续与这个社区一起成长,并为提升产品的新功能和增强功能做出贡献。我也成为了 Qdrant 的倡导者,将这个项目介绍给我的许多同事和科技行业的朋友。我很高兴看到我的网络中出现新的用户和贡献者!
如果您想尝试我的工作,请阅读文档,然后注册一个免费的云账户或下载Docker 镜像。我期待看到人们如何在自己的应用程序中使用我的工作!
