Cypher:大型嵌套WHERE/CONTAINS子句的性能含义是什么



Im使用具有大型WHERE子句的查询:

WHERE (
(n.val CONTAINS 'wrd1-1' AND n.val CONTAINS 'wrd1-2' AND n.val CONTAINS 'wrd1-3') OR
(n.val CONTAINS 'wrd2-1' AND n.val CONTAINS 'wrd2-2' AND n.val CONTAINS 'wrd2-3') OR
(n.val CONTAINS 'wrd3-1' AND n.val CONTAINS 'wrd3-2' AND n.val CONTAINS 'wrd3-3') OR
.
.
.
(n.val CONTAINS 'wrd20-1' AND n.val CONTAINS 'wrd20-2' AND n.val CONTAINS 'wrd20-3')
)

n.val是一个字符串,我希望匹配tri-grams(wrd(。我使用CONTAINS实现词序独立性

  1. 在Cypher中有更好的方法吗
  2. RDBMS能更好地处理这个问题吗

纯粹为了简化Cypher查询本身(不一定是性能(,如果您可以将要搜索的单词收集到列表中,那么无论有多少单词或有多少集合,您的查询都可以是稳定的。

这里有一个例子:

// below for example input, though you would want to parameterize this
WITH [['wrd1-1', 'wrd1-2', 'wrd1-3'], ['wrd2-1', 'wrd2-2', 'wrd2-3'], ['wrd3-1', 'wrd3-2', 'wrd3-3']] as searchData
MATCH (n:Node) // or whatever type you're matching on
UNWIND searchData as words
WITH n 
WHERE all(word IN words WHERE n.val CONTAINS word) 
RETURN n

使用all()谓词函数的最后一个WHERE子句将确保该节点上的CONTAINS检查对于集合中的所有单词都必须为true。

就性能而言,您提到您正在使用CONTAINS实现词序独立性。如果val属性只包含完整的单词,并且您的目标是只查找属性中的完整单词,那么有几种不同的方法可以处理此问题。

如果val属性中当前的单词数与您将要搜索的单词数相同(例如,始终为3个单词,其中您将始终搜索相同的3个单词(,那么您可以重构数据,使val始终按字母顺序排列并小写,然后为属性编制索引,这样,当您执行查找时,您可以将输入更改为相同的格式(小写和字母(,并执行精确的查找,这将利用索引。

如果您需要能够在节点上查询单词的子集(但您仍然只查找整个单词(,那么您可以考虑重构数据,使单词成为与原始节点有关系的自己的节点,而不是节点上的val属性。

这样,您可以对:Word节点执行索引查找,并从中匹配到与您匹配的所有:Word节点都有关系的节点。

下面是一篇关于执行匹配交集的文章,它解释了几种实现这种匹配的方法。

最新更新