同福

在Elasticsearch里使用aggs实现SQL的group by语句功能【20210802】

介绍

介绍

福哥在给同福网增加全文搜索功能的时候遇到了一个需求,福哥想要调出“热门标签”列表,这个可以通过SQL语句的Group by来实现。但是福哥想通过Elasticsearch来完成,毕竟ES的执行效率要快很多,那么如何通过Elasticsearch来实现类似SQL的Group by语句的效果呢?

通过研究发现了在Elasticsearch里面可以使用aggregations来模拟SQL的Group by语句效果,它不仅仅可以模拟还有更强大的功能,我们来学习一下吧~~

分组

首先我们先来一个例子,福哥要实现根据文档的作者ID进行分组,从而拿到一组作者ID列表。

SQL

SELECT authorId, count(*) as doc_count FROM docs GROUP BY authorId LIMIT 6

ES

{
  "from": 0,
  "size": 0,
  "aggs": {
    "gb_authorId": {
      "terms": {
        "field": "authorId",
        "size": 6
      }
    }
  }
}

分组后排序

接下来我们再来一个例子,福哥要根据文档绑定的标签ID进行分组,然后再根据分组后的数量进行排序,从而得到一组文档最多的标签ID列表。

SQL

SELECT dt.tagId, count(*) as doc_count FROM docs d
INNER JOIN doc_tag dt
ON d.docId = dt.docId 
GROUP BY dt.tagId ORDER BY doc_count LIMIT 6

ES

{
  "from": 0,
  "size": 0,
  "aggs": {
    "gb_tagIds": {
      "terms": {
        "field": "tagIds",
        "order": {
          "_count": "desc"
        },
        "size": 6
      }
    }
  }
}

可以发现一个有趣的事情,在SQL里面为了实现这个目的用到了关联表进行分组。但是在ES里面可以直接对数组属性进行分组处理,而且排序语句没有变化,这个真的是很爽啊~~

排序字段

分组后的排序可以根据不同的依据进行排序,大家跟着福哥来了解一下吧!

_term

根据分组的字段的值进行排序,就是Group by后面的字段

_count

根据分组文档的数量进行排序,就是SELECT里面的count(*)出来的数字

总结

今天福哥给大家演示了在ES里通过aggs来实现SQL里的Group by的分组功能的效果,同样的分组目的使用ES可以获得更高的效率,这个在数量越大的时候效果越明显~~