neo4j-搜索用户时基于适合性的评分

qxgroojn  于 2021-07-13  发布在  Java
关注(0)|答案(3)|浏览(371)

我需要在我的neo4j数据库中搜索用户的名字和姓氏。查询结果应按它们与搜索查询的匹配程度排序。我们希望搜索输入是两个单词(first/last或last/first name)。
到目前为止,我们使用的查询搜索包含名字的用户,然后使用union all再次匹配包含姓氏的用户。假设搜索输入为“first last”。所以我们的问题是:

MATCH (u:User) WHERE u.first_name =~'(?i).*first.*' RETURN u
UNION ALL u.last_name =~'(?i).*last.*' return u
UNION ALL u.first_name =~'(?i).*last.*' RETURN u
UNION ALL u.last_name =~'(?i).*first.*' return u

因此,具有搜索输入的名字和姓氏的用户将在查询结果中出现两次。然后在java后端计算每个用户出现的次数(每个用户有一个唯一的用户名),然后排序。
我希望避免在java后端进行排序和计数,如果可能的话,只使用一个查询。
任何帮助都将不胜感激。谢谢。

rpppsulh

rpppsulh1#

对于类似文本的搜索查询,cypher可能不是您想要的方式。neo4j实际上支持由apachelucene实现的遗留索引,我向您推荐这些索引,因为它是用于文本索引的。lucene甚至为您提供了丰富的查询语言来改进您的搜索。
如果您尝试使用cypher方法,那么最终将编写大量复杂的后端代码,而且您的匹配仍然相当幼稚;在本例中,姓氏和名的字符匹配仍然需要一个字符,而拼写错误的字符将找不到匹配的字符。
传统索引的文档从这里开始。一定要阅读“得分”的子页,因为最后,我想这就是你想要的。还要确保检查lucene索引的额外特性,因为它将开始向您展示您可以用lucene做的更酷的事情(比如复合查询),这是通过cypher不可能做到的。
好消息是neo4j可以做到这一点,它的工作非常好。坏消息是,有些东西只能通过javaapi获得,而不能像您提供的示例所假设的那样直接从cypher获得。

aiqt4smr

aiqt4smr2#

您还可以将其合并到一个regexp中:

MATCH (u:User) 
WHERE (u.first_name+" "+u.last_name) =~'(?i).*(first|last).*' RETURN u

最好将两者存储在一个“name”属性中。在neo4j 3.x中 CONTAINS 也将使用索引,但当前区分大小写。

1l5u6lss

1l5u6lss3#

检查我目前在搜索查询中使用的基本匹配精度的一种方法是,简单地对照结果字符串检查搜索键的字符串长度,并根据计算出的差值对结果列表进行排序。

MATCH (u:User) WHERE u.name ~= {searchKeyRegex}
RETURN u.name, ABS( LENGTH(u.name) - LENGTH({searchKey}) ) as precision
ORDER BY precision ASC LIMIT {limit}

我不得不承认这仍然是一种昂贵的暴力,但到目前为止,它似乎做的把戏。

相关问题