join - 在 ElasticSearch 中模拟连接

标签 join elasticsearch

假设 ES 索引中的文档有两个字段,user_idaction_id。如何统计用户,使得同时存在action_id = 1action_id = 2 的文档?

等效的 SQL 是

SELECT COUNT(DISTINCT `a`.`uuid`)
FROM `action` AS `a`
JOIN `action` AS `b` ON `a`.`user_id` = `b`.`user_id`
WHERE `a`.`action_id` = 1
AND `b`.`action_id` = 2

我找到了这样做的唯一方法:使用这些 action_id 请求两次所有唯一的 user_id 并在 ES 客户端上找到结果集的交集。然而,这种方法需要从 ES 传输数兆字节的数据,所以我正在寻找替代方法。

最佳答案

你可以这样做:

  • 首先,您有一个查询仅使用 12 操作来过滤您的文档(我不知道您是否可以使用其他操作类型)
  • 那么神奇的是聚合
    • 第一个聚合是针对 user_idterms,这样您就可以每个用户
    • 进行单独计算
    • 然后您使用基数 子聚合来计算每个用户的不同操作数。由于查询是针对 12 的操作,因此该数字只能是 1 或 2
    • 然后您使用 bucket_selector 子聚合来仅保留基数结果为 2 的用户。
{
  "size": 0,
  "query": {
    "bool": {
      "should": [
        {
          "terms": {
            "action_id": [
              1,
              2
            ]
          }
        }
      ]
    }
  },
  "aggs": {
    "users": {
      "terms": {
        "field": "user_id",
        "size": 10
      },
      "aggs": {
        "actions": {
          "cardinality": {
            "field": "action_id"
          }
        },
        "actions_count_bucket_filter": {
          "bucket_selector": {
            "buckets_path": {
              "totalActions": "actions"
            },
            "script": "totalActions >= 2"
          }
        }
      }
    }
  }
}

结果如下所示:

   "aggregations": {
      "users": {
         "doc_count_error_upper_bound": 0,
         "sum_other_doc_count": 0,
         "buckets": [
            {
               "key": 1,
               "doc_count": 2,
               "actions": {
                  "value": 2
               }
            },
            {
               "key": 5,
               "doc_count": 2,
               "actions": {
                  "value": 2
               }
            }
         ]
      }
   }

key 是其操作为1 2 的user_id。 bucket_selector 聚合在 ES 的 2.x+ 版本中可用。

关于join - 在 ElasticSearch 中模拟连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38266745/

相关文章:

maven - 使用 “spring-boot-starter-parent”时如何在Maven中使用较低的Elastic搜索版本

elasticsearch - 我们如何更改Elasticsearch集群名称的字符长度

mysql - 使用子查询与 LEFT JOIN 一起选择 MAX 值

mysql - 使用 MySQL 在其他表中搜索并求和

database - 如何在表网关 ZF2 中添加带有 JOIN ON 子句的 IN 语句

具有 3 个节点的 ElasticSearch 可用性/分区容差

sql - ActiveRecord::Relation join,如何将连接表的一列添加到新名称的查询结果中?

sql - JOIN 语句(SQL)中的 "left"表和 "right"表到底是哪个表?

sorting - Elasticsearch 基数排序错误

elasticsearch - 如何处理 ElasticSearch 字段中的标点符号