《Elastic Stack 实战手册》——三、产品能力——3.5 进阶篇——3.5.4.Graph (上) https://developer.aliyun.com/article/1228725
Elasticsearch 的实现方式
Elasticsearch 的 Graph 功能始于 5.5 版本,属于 X-pack 的扩展功能组,从 API 的路径
/_graph/explore 可以看出,其定位更倾向于是探索分析,即在已有的索引上通过聚合的方式进行分析。
常规的 graph 查询可以理解为,先进行两层嵌套的 terms 聚合,再将查询结果以 vertexs 和connections 的数据模型进行返回。
在使用 Graph 功能时,有3个核心要素,分别是 vertices、connections、controls,前两者主要用于确定图查询中,前者通过哪些字段产生,后者用于控制一些查询细节。
如希望通过点击日志探查用户的搜索词和点击的产品间的关联,可通过如下查询
POST clicklogs/_graph/explore { "query": { "match": { "query.raw": "midi" } }, "vertices": [ { "field": "product" } ], "connections": { "vertices": [ { "field": "query.raw" } ] } }
查询语句中
l vertices 用于指定对哪些字段的内容感兴趣,后续会作为 target 节点处理,对应的字段必须是已索引的字段。
l connections 用于指定希望哪些字段和 vetices 的内容进行关联,后续会作为 source 节点处理,connections 也支持使用 query 缩小关联内容的范围。
这个查询会以聚合的方式得到最终结果,会产生类似两层嵌套 aggs 的查询效果
"aggs": { "vertices": { "terms": { "field": "product" }, "aggs": { "connections": { "terms": { "field": "query.raw" } } } } }
查询结果会返回 vertices 和 connections 两个数组,通过这两部分数据,即可构成一个有向图(方向是由 connections 中设定的 query.raw 指向 vertices 中设定的 product)。
为了能更直观的反映每个节点,和每条边的重要程度,vertices 和 connections 的元素中均会额外返回一个 weight,这点也是 Elasticsearch Graph 区别于其他图数据库查询的功能点之一。
"vertices": [ { "field": "query.raw", "term": "midi cable", "weight": 0.08745858139552132, "depth": 1 }, { "field": "product", "term": "8567446", "weight": 0.13247784285434397, "depth": 0 } ], "connections": [ { "source": 0, "target": 1, "weight": 0.04802242866755111, "doc_count": 13 } ]
除了上述例子所举的常规查询模式外,Elasticsearch 的 Graph API 还可以通过 controls 控制采样规模和 weight 的计算:
use_significance(默认 false)
如设置为 true,第二层的聚合将会变为 Significant Terms,得到的 weight 会是通过前置和后置频率算出的,可用来发现一些有趣,或不寻常的节点或关系。
sample_size(默认100)
通过减少采样规模,可以有效提高检索效率
除此以外,Elasticsearch 还支持通过 Kibana 配置 Graph 相关的可视化页面,借此可以快速将上述查询得到的结果以图形化的方式进行展现。以下示例基于 7.10 操作:
1、在 Kibana 中选择 Graph 进入导航页面;
2、选取一个数据源,即库中已存在的索引;
添加字段并触发查询即可得到如下的图结构分析页面 (可变更颜色区分节点),上文提及的 weight 值将通过节点间连线的粗细体现。
总结
高可用和近实时的能力
Elasticsearch 的 Graph 功能通过 X-pack 提供,其优点是可以对库中已有的数据,快速进行分析,且具备可视化能力。其天然具备高可用和近实时的能力。
千万以及亿级的数据进行 Graph 分析
依托于已有的倒排索引和聚合功能,可以快速以 vertices 和 connections 的数据模型呈现结果。由于聚合本身需要消耗较大的内存和计算量,在使用时需要留意数据量级和系统资源,在资源允许的情况下,可以支持对千万以及亿级的数据进行 Graph 分析。
当然 Elasticsearch 的 Graph 也存在一定局限性,它本身定位是对已有索引进行分析,因此不适合需要建模管理图结构数据的场景,且无法对多跳的路径查询进行有效支持。
并且 Elasticsearch Graph 内部的处理逻辑,是通过对索引进行字段级的聚合,因此产生关系的上下游节点仅限于同一索引中的不同字段。
综上,如果你希望发现索引中不同字段的一些潜在价值,不妨使用 Elasticsearch Graph 功能来进行探索。
参考资料
l https://www.elastic.co/guide/en/elasticsearch/reference/master/graph-explore-api.html
l https://www.elastic.co/guide/en/kibana/current/graph-getting-started.html