如何在运行时从 Solr 中过滤大量的 ids

How to filter a huge list of ids from Solr at runtime

我有一个 products 的索引是 Solr。我需要为每个客户提供定制的产品列表,这样我就必须为每个客户排除一些特定产品。 目前,我将这种客户与排除产品的关系存储在 SQL 数据库中,然后使用术语查询在 Solr 中过滤它们。有没有一种方法可以将这种关系存储在 Solr 本身中,这样我就不必每次都先从 SQL 计算排除列表。

与我们在 elasticsearch 中使用 https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html

所做的非常相似

我想在 Solr 中做的可能方法:

  1. 在产品索引本身中保留客户列表,并对其进行过滤。但如果我必须重新索引所有文档,这真的会很痛苦。列表也可能很大。

  2. 我能想到的另一种方法是维护一个单独的核心来为每个客户保存文档并排除 product_id 并使用 {!join} 执行连接以过滤出客户的产品.它是一个可扩展的解决方案吗?

在 Solr 中存储此类数据的理想方法应该是什么。

SQL 数据库是否存在任何性能问题?查询数据库并获取 ID,然后将它们发送到 Solr 是完全没问题的。您将避免复杂性和数据重复。无论如何,您也必须进行一些计算才能将这些 ID 发送到 Solr。

但要回答您的问题,是的,您确实可以将每个客户排除的产品 ID 存储在单独的索引中。您将使用多值字段和 update using atomic updates。如果这样做,请确保保持索引模式简单,不使用用于 ID 的分析器(只需使用 string 类型,不使用任何分词器或过滤器)。

您不需要执行 Solr 连接查询。您只需查找每个客户的产品 ID(第一个查询)并将它们作为 CSV 进行处理,然后使用从索引中检索到的产品 ID 执行 terms query(第二个查询)。

你需要找到最适合你的折衷方案

最佳查询时间性能 您向产品索引添加一个字段(多值):allowed_users(或 forbidden_users),具体取决于基数(您想要最小化)。 这将需要第一次重新索引并为每个用户权限更改进行索引更新。 为了减少网络流量并优化更新,您可以查看原子更新[1] .

最佳指数时间表现 如果以前的方法在您的情况下不可行或不能满足您的要求,您可以尝试优化索引端。 您可以在单独的集合中索引文档:

<Id>
<product_id>
<user_id>

您可以使用查询时连接来过滤当前用户的集合,然后取回产品以在您的查询中过滤它们。

所以基本上,您已经考虑了这两个想法:)

[1] https://lucene.apache.org/solr/guide/6_6/updating-parts-of-documents.html