Elasticsearch示例中Answer文档与Question文档tags的关联机制是什么?
这个关联是通过Elasticsearch的父子文档机制加上嵌套聚合查询实现的,具体分两个阶段:
一、数据写入阶段:建立父子文档的物理绑定
在写入数据时,Answer文档就已经和对应的Question文档绑定在一起:
父文档(Question)写入示例
PUT child_example/_doc/1 { "join": { "name": "question" }, "body": "<p>I have Windows 2003 server and i bought a new Windows 2008 server...", "title": "Whats the best way to file transfer my site from server to a newer one?", "tags": [ "windows-server-2003", "windows-server-2008", "file-transfer" ] }
这里ID为1的文档是父文档,join字段标记其类型为question,同时包含tags数组。
子文档(Answer)写入示例
PUT child_example/_doc/2?routing=1 { "join": { "name": "answer", "parent": "1" }, "owner": { "location": "Norfolk, United Kingdom", "display_name": "Sam", "id": 48 }, "body": "<p>Unfortunately you're pretty much limited to FTP...", "creation_date": "2009-05-04T13:45:37.030" }
- 子文档通过
join.parent: "1"明确指定父文档ID为1,告诉Elasticsearch它属于ID为1的Question - URL参数
routing=1强制子文档和父文档存入同一个分片(Elasticsearch要求父子文档必须在同一片分片,否则无法关联)
这一步完成后,Elasticsearch内部就记录了两者的父子关系。
二、查询阶段:通过聚合关联tags和回答者
查询语句通过三层嵌套聚合,把父文档的tags和子文档的回答者关联起来:
聚合查询示例
POST child_example/_search?size=0 { "aggs": { "top-tags": { "terms": { "field": "tags.keyword", "size": 10 }, "aggs": { "to-answers": { "children": { "type" : "answer" }, "aggs": { "top-names": { "terms": { "field": "owner.display_name.keyword", "size": 10 } } } } } } } }
聚合的执行逻辑:
- 第一层
top-tags聚合:按父文档的tags.keyword字段分组,得到每个标签对应的父文档集合(比如windows-server-2003标签对应ID为1的Question) - 第二层
to-answers聚合:使用children聚合类型指定answer,Elasticsearch会自动匹配当前标签分组下所有父文档对应的子Answer文档(也就是ID为2的Answer) - 第三层
top-names聚合:在匹配到的Answer文档中,统计owner.display_name.keyword的出现频次,得到该标签下的热门回答者
简单来说,就是先按标签把父文档归类,再通过父子关联找到每个类别下的所有回答,最后统计这些回答里的热门作者,以此建立起标签和回答者的关联。
内容的提问来源于stack exchange,提问作者yulinxp
相关产品推荐
相关产品推荐

