我正在尝试对弹性搜索进行内部查询,类似于Solr Wiki上的示例
https://wiki.apache.org/solr/Join
SELECT xxx, yyy
FROM collection1
WHERE outer_id IN (SELECT inner_id FROM collection1 where zzz = "vvv")
在弹性搜索中是否可以做类似的事情?
答案 0 :(得分:0)
如果您的文档共享相同的ID,则可以。该技术称为应用程序侧联接(应用程序,因为您/您的应用程序确定ID而不是ES引擎,因此称为应用程序)。
一个例子是:您有2个索引“学生和课程”;并且您希望所有“课程”文档中都包含名称为“ Jeff”的学生。假设在“学生”索引中,您有一个名为“课程”的字段,其中存储了该学生所注册的课程的ID。
在这种情况下,如果要使用“应用程序侧联接”,则应首先查询“学生”索引,获取课程ID,并检查名称字段中是否存在名称“ Jeff”。之后,您对“课程”索引进行第二次查询,询问其ID与您从第一次查询中收到的ID相匹配的那些文档。这是最接近通过弹性搜索获得的“连接”。
通常(在搜索模型/以及与搜索相关的技术(例如ES)中),最好对所需的“连接型”行为使用另一种技术,这称为“索引非规范化/或数据非规范化”,基本上就是在另一个索引中重复(部分/全部)索引信息。在此示例中,这意味着在学生索引中重复您的部分课程信息(这样您就不必发出第二次查询)。
即使数据非规范化导致数据使用量增加,也可以减少搜索时间,因为您避免发出2个(或更多)查询;仅需1个查询,即可为您提供所有合并的数据。如果您使用普通的关系规范化数据库来存储规范的数据表示形式,并且仅将ES用作某些关键查询的搜索模型,则强烈建议您对非关键性数据进行规范化并在仅索引中重复,以避免这种类型的应用程序侧加入。
在某些特定情况下,分隔索引(使用应用程序侧联接而不是非规范化方法)更好。此类情况之一是,如果您对联接的数据进行了频繁的更新,因为您对另一个索引上的数据进行了非规范化处理;那么您将不得不跨索引的所有实例更新数据,这是不可接受的。
希望有帮助。