在Neo4j中匹配,排序和返回多个节点

时间:2014-09-12 06:27:26

标签: neo4j cypher

我在Neo4j中有多个节点,他们有像人,技能,兴趣,公司等标签(大约8-9个不同的标签)。我想搜索/匹配这些节点中的属性,并返回有限的结果,比如50个人。

我还想知道一个人是否在具有不同标签的多个不同节点中点击并且能够基于该排序对他们进行排序,并且可能在排名上表明Person节点中的匹配排名高于匹配兴趣节点。

我尝试了不同的方法,但发现很难在一个查询中使用9种不同的标签来完成所有这些操作。我还需要有关每个人返回的信息,这是所有不同节点(人员,技能,公司等)的组合。

这是我到目前为止所做的:

MATCH (person:Person)
WHERE person.name =~ '(?i).*some_search_query.*'
RETURN COLLECT(DISTINCT person) as persons 

UNION ALL 

MATCH(skill:Skill) <- [:HAS_SKILL] - (person:Person) 
WHERE skill.name =~ '(?i).*some_search_query.*'
RETURN COLLECT(DISTINCT person) as persons

UNION ALL
etc...

使用几个较小的密码查询来处理此问题是否更好,然后在返回后合并结果?

如何改进此查询以包含限制和排序,并返回每个人的所有信息(技能,公司,兴趣等)?

在性能方面是否有更好的方法?

如果重要的话,我正在使用Node.js。

更新

我现在有以下查询:

OPTIONAL MATCH (person:Person)
WHERE person.name =~ '(?i).*some_search_query.*'
WITH COLLECT(DISTINCT person) as matchInPerson

OPTIONAL MATCH(skill:Skill) <- [:HAS_SKILL] - (person:Person)
WHERE skill.name =~ '(?i).*some_search_query.*'
WITH COLLECT(DISTINCT person) as matchInSkill, matchInPerson

OPTIONAL MATCH(group:Skill) <- [:MEMBER_OF_GROUP] - (person:Person)
WHERE group.name =~ '(?i).*some_search_query.*'
WITH COLLECT(DISTINCT person) as matchInGroups, matchInPerson, matchInSkill

OPTIONAL MATCH(company:Company) <- [rel:WORKED_AT] - (person:Person)
WHERE company.name =~ '(?i).*some_search_query.*' OR rel.description =~ '(?i).*some_search_query.*'
WITH COLLECT(DISTINCT person) as matchInCompany, matchInPerson, matchInSkill, matchInGroups

OPTIONAL MATCH(country:Country) <- [:LIVES_IN] - (person:Person)
WHERE country.name =~ '(?i).*some_search_query.*'
WITH COLLECT(DISTINCT person) as matchInCountry, matchInPerson, matchInSkill, matchInGroups, matchInCompany

OPTIONAL MATCH(city:City) <- [:LIVES_IN] - (person:Person)
WHERE city.name =~ '(?i).*some_search_query.*'
WITH COLLECT(DISTINCT person) as matchInCity, matchInPerson, matchInSkill, matchInGroups, matchInCompany, matchInCountry

OPTIONAL MATCH(interest:Interest) <- [:HAS_INTEREST] - (person:Person)
WHERE interest.name =~ '(?i).*some_search_query.*'
WITH COLLECT(DISTINCT person) as matchInInterest, matchInPerson, matchInSkill, matchInGroups, matchInCompany, matchInCountry, matchInCity

OPTIONAL MATCH(industry:Industry) <- [*1..2] - (person:Person)
WHERE industry.name =~ '(?i).*some_search_query.*'
WITH COLLECT(DISTINCT person) as matchInIndustry, matchInPerson, matchInSkill, matchInGroups, matchInCompany, matchInCountry, matchInCity, matchInInterest

 OPTIONAL MATCH(certification:Certification) <- [rel:HAS_CERTIFICATION] - (person:Person)
WHERE certification.name =~ '(?i).*some_search_query.*' OR rel.by =~ '(?i).*some_search_query.*'
WITH COLLECT(DISTINCT person) as matchInCertification, matchInPerson, matchInSkill, matchInGroups, matchInCompany, matchInCountry, matchInCity, matchInInterest, matchInIndustry

OPTIONAL MATCH(project:Project) <- [:WORKED_ON_PROJECT] - (person:Person)
WHERE project.name =~ '(?i).*some_search_query.*'
WITH COLLECT(DISTINCT person) as matchInProject, matchInPerson, matchInSkill, matchInGroups, matchInCompany, matchInCountry, matchInCity, matchInInterest, matchInIndustry, matchInCertification

RETURN matchInPerson, matchInSkill, matchInGroups, matchInCompany, matchInCountry, matchInCity, matchInInterest, matchInIndustry, matchInCertification, matchInProject

返回类似以下内容(删除结果):

[
   {
      "matchInPerson": [],
      "matchInSkill": [],
      "matchInGroups": [],
      "matchInCompany": [],
      "matchInCountry": [],
      "matchInCity": [],
      "matchInInterest": [],
      "matchInIndustry": [],
      "matchInCertification": [],
      "matchInProject": []
   }
]

matchInPerson和matchInSkills等现在可以有重复,这是有意的,因为我想看看我是否可以在几个节点中匹配。

我现在的问题是我需要一些方法来删除重复项,然后可能会为具有重复项的人添加属性,例如每个重复项的person.matches + = 1(或者计算多少数学的数学我有一个人)。

也许最重要的是,我想限制响应(重复删除和计算后),因为我不想返回数千个结果。对重复命中数量的结果进行排序也很不错。

希望这在密码查询本身中是可以实现的,这样我就不必处理查询中的结果。

0 个答案:

没有答案