【问题标题】:How to exclude a large set of of ids from elasticsearch result?如何从弹性搜索结果中排除大量 id?
【发布时间】:2018-03-08 05:07:21
【问题描述】:

我有很多 产品 在 elasticsearch 中被索引。我需要从 elasticsearch 中的查询中排除一个 id 列表(我从 SQL 数据库中获取)。 假设 产品 存储为,

{
  "id" : "1",
  "name" : "shirt",
  "size" : "xl"
}

我们使用弹性搜索根据某种算法向客户显示推荐产品列表。 如果客户将产品标记为“不感兴趣”,我们不必再次向他展示该产品。 我们将此类产品保存在单独的 SQL 表中,product_idcustomer_idstatus 为“not_interested”。

现在,在运行时为客户获取推荐时,我们从 SQL 数据库中获取“not_interested”产品列表,并在 elasticsearch 的非过滤器中发送 product_ids 数组以将它们排除在外推荐。 但是当 product_ids 数组的大小变得太大时,问题就出现了。

我应该如何在elasticsearch中存储product_id和customer_id映射 仅使用 elasticsearch 在运行时过滤掉“not_interested”产品?

将它们存储为嵌套对象或父/子文档是否有意义?或者一些完全其他的存储方式,这样我就可以有效地从结果中排除一些 id。

【问题讨论】:

    标签: elasticsearch solr lucene elastic-stack recommendation-engine


    【解决方案1】:

    您可以使用terms query 有效地排除 ID(或任何其他文字字符串)。

    Elasticsearch 和 Solr 都有这个。它非常强大且非常高效。

    Elasticsearch 有这个 IDS query。此查询实际上是对 _uid 字段的术语查询。确保在 bool 查询中的 mustNot 子句中使用此查询。见:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-ids-query.html

    在 Solr 中,您可以在 fq 中使用 terms query,例如 fq=-{!terms f=id}doc334,doc125,doc777,doc321,doc253。注意减号表示它是否定的。见:http://yonik.com/solr-terms-query/

    【讨论】:

    • 如果要否定的 id 列表是一个巨大的列表,这不会是一个问题。假设有数万个这样的文档 ID。
    • 如果您在服务器端执行此操作不会有问题,因为此查询已针对您的用例进行了优化。我已经这样做了数万次,它仍然非常快!要查看它何时变慢,您必须对此进行测试,因为这取决于您的索引大小,但这将是一个非常高的数字。
    • @drjz elasticsearch 中的实现在elastic.co/guide/en/elasticsearch/reference/current/… 有很好的记录。我可以在 Solr 中也有类似的东西吗? fq=-{!terms f=id}doc334,doc125,doc777,doc321,doc253 ,如果 docId 很大,将达到查询长度限制。有没有其他方法可以在 Solr 中实现这一点,方法已经在 ES 中完成。
    • Solr 没有限制。由于您在服务器端针对 Solr 执行此请求,因此 GET 请求应该没有限制。如果遇到限制,很可能是您的 servlet 容器(Jetty、Tomcat、Nginx)并考虑在那里提高限制。
    • 谢谢,增加 Jetty 的限制对我有用。但是,我仍然必须从 SQL 计算排除列表,然后在 Solr 查询中传递它。有没有办法可以在 Solr 本身上为每个客户索引我的排除列表,并在运行时为给定客户过滤掉它。我能想到的一种方法是维护一个单独的核心来保存每个客户的文档并排除 product_id 使用 {!join} 执行连接以过滤掉客户的产品。它是一个可扩展的解决方案吗?
    【解决方案2】:

    使用“ids”查询:

    https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-ids-query.html

    {
        "query": {
            "ids" : {
                "type" : "my_type",
                "values" : ["1", "4", "100"]
            }
        }
    }
    

    包裹在一个布尔值中 > must_not.

    【讨论】:

      【解决方案3】:

      must_not 部分下添加Terms,如下所示:

      {
        "must_not": [
          {
            "terms": {
              "id": [
                "1",
                "3",
                "5"
              ]
            }
          }
        ]
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-10-10
        • 2014-06-17
        • 1970-01-01
        • 2021-08-04
        • 2014-07-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多