在Elasticsearch中寻找朋友的朋友

时间:2016-01-26 16:29:31

标签: elasticsearch relationship

我有一个包含员工,项目和公司的系统。这些实体之间的关系当前存储在名为Relationships的单个SQL表中。该表的额外简化版本如下所示:

  EntityID | EntityCategory | TypeID  | AssocType
    123    |    Employee    |   ABC   |  Project
    123    |    Employee    |   DEF   |  Project
    789    |    Company     |   ABC   |  Project
    789    |    Company     |   DEF   |  Project

(我应该注意到这个数据库的真实版本有更多的实体类型 - 例如,联系人也可以与项目或员工相关联,因此类别/类型列)我想找到哪些员工和公司“知道”彼此通过与项目的相互关系 - 基本上是对朋友的朋友的有限搜索。我们将此称为“间接关系”。在SQL中,我可以这样做:

SELECT R.EntityID AS EmployeeID, R2.EntityID AS CompanyID, 
Count(R.TypeID) as SharedProjectCount
FROM Relationships as R 
INNER JOIN Relationships as R2 ON 
 R.TypeID=R2.TypeID AND R2.EntityCategory='Company' AND R2.AssocType='Project'
WHERE R.EntityCategory='Employee' AND R.AssocType='Project'
GROUP BY R.EntityID, R2.EntityID

得到如下结果集:

  EmployeeID | CompanyID | SharedProjectCount
      123    |    789    |          2

我希望能够在Elasticsearch中执行此操作。数据的存储方式略有不同:

 [
  {EmployeeID:123, ProjectID:ABC},
  {EmployeeID:123, ProjectID:DEF},
  {CompanyID:789,  ProjectID:ABC},
  {CompanyID:789,  ProjectID:DEF}
 ]

我的问题的核心是:我想将此关系数据批量提取到Elasticsearch中。直接关系都在SQL表中并且需要检索。在SQL上计算间接关系很难,我想尝试使用Elasticsearch来组装它们。有没有办法可以通过项目请求(例如)所有任何公司相关的员工,以类似{EmployeeID:123, CompanyID:789,SharedProjectCount:2}

我已经知道像Neo4j这样的东西是使用这样的图形的最佳工具;请理解这不是一个选项,我特别想找到一种方法来处理Elasticsearch。我愿意改变Elasticsearch中的数据结构。

1 个答案:

答案 0 :(得分:0)

在“project_id”和terms 子聚合上使用top_hits聚合运行match_all查询。

这应该为您提供按ProjectID分组的EmployeeID和CompanyID记录列表(适用于所有项目)。