我想在弹性搜索中存储员工层次结构。首席财务官,首席技术官,首席运营官等向首席执行官汇报。每个员工都可以拥有自己的报告。
我认为上面可以使用弹性搜索父子关系来完成。我们是否可以编写查询以在一次调用中获取所有报告者(直接报告者和子报告者)。 例如,如果我们查询首席执行官,我们应该让所有员工和首席财务官,我们应该让财务部门的员工。
RDMS中存在类似SQL Server的CTE。
答案 0 :(得分:4)
ES中的亲子关系是:
_parent
与其联系并妥善路由。所以,没有简单的方法(没有办法实际存储任何关系数据的正常形式,因为ES在非关系数据库中)。解决方法:
has_parent
/ has_child
查询查询文档(只有1级关系适用于此)nested
个对象(注意,如果任何成员更改,此模型会重新索引整个文档)答案 1 :(得分:2)
首先,避免以关系数据库的方式考虑ES。 ES不太适合连接/关系,尽管它可以通过父/子关系实现类似的效果。甚至不要考虑可能涉及不确定深度的连接。 CTE可以轻松处理,但并非所有关系数据库都支持CTE AFAIK(MySQL为一体)。
亲子关系比IMMO的价值更大。子文档被路由到父母居住的碎片。在您的树的情况下,所有文档最终将追溯到根文档,这将导致所有文档驻留在单个分片中。树的深度可能非常大(在一个不那么小的组织中超过4或5)。此外,如果您使用此解决方案,根据其ID从ES检索(通过GET
API)特定子文档是非常不方便的,因为您必须指定其父ID一直到它的ID根
我认为最好将PATH
从根目录存储到但不包括当前员工作为ID列表。因此,每个员工都有一个类似的字段:
"superiors": [CEO_ID, CTO_ID, ... , HER_DIRECT_MANAGER_ID],
因此它完全非规范化,您的应用程序必须为此列表做好准备。
通过此设置,获取员工的所有下属:
superiors
字段中的ID以及自己的ID。terms
字段上执行superiors
个攻击,您将拥有该员工的所有下属。我必须承认至少需要两个查询。第一个是GET
请求检索此员工的superiors
字段,然后是第二个查询以执行上述操作。
另外,不要担心由于非规范化造成的重复。 ES可以处理比您在此处保存的数据更多的数据。