我需要在我的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后端进行排序和计数,如果可能的话,只使用一个查询。
任何帮助都将不胜感激。谢谢。
3条答案
按热度按时间rpppsulh1#
对于类似文本的搜索查询,cypher可能不是您想要的方式。neo4j实际上支持由apachelucene实现的遗留索引,我向您推荐这些索引,因为它是用于文本索引的。lucene甚至为您提供了丰富的查询语言来改进您的搜索。
如果您尝试使用cypher方法,那么最终将编写大量复杂的后端代码,而且您的匹配仍然相当幼稚;在本例中,姓氏和名的字符匹配仍然需要一个字符,而拼写错误的字符将找不到匹配的字符。
传统索引的文档从这里开始。一定要阅读“得分”的子页,因为最后,我想这就是你想要的。还要确保检查lucene索引的额外特性,因为它将开始向您展示您可以用lucene做的更酷的事情(比如复合查询),这是通过cypher不可能做到的。
好消息是neo4j可以做到这一点,它的工作非常好。坏消息是,有些东西只能通过javaapi获得,而不能像您提供的示例所假设的那样直接从cypher获得。
aiqt4smr2#
您还可以将其合并到一个regexp中:
最好将两者存储在一个“name”属性中。在neo4j 3.x中
CONTAINS
也将使用索引,但当前区分大小写。1l5u6lss3#
检查我目前在搜索查询中使用的基本匹配精度的一种方法是,简单地对照结果字符串检查搜索键的字符串长度,并根据计算出的差值对结果列表进行排序。
我不得不承认这仍然是一种昂贵的暴力,但到目前为止,它似乎做的把戏。