Neo4j Cypher:在一组匹配的节点之间查找公共节点 [英] Neo4j Cypher: Find common nodes between a set of matched nodes

查看:34
本文介绍了Neo4j Cypher:在一组匹配的节点之间查找公共节点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

与问题类似,此处

我有以下节点:文章和单词.每个单词都通过 MENTIONED 关系连接到文章.

I have the following nodes: Article and Words. Each word is connected to an article by a MENTIONED relationship.

我需要查询所有具有常用词的文章,其中常用词列表是动态的.从客户的角度来看,我正在传递一个单词列表,并期望返回具有这些单词相同之处的文章的结果.

I need to query all articles that have common words where the list of common words is dynamic. From the clients perspective, I am passing back a list of words and expecting back a results of articles that have those words in common.

以下查询可以完成

WITH ["orange", "apple"] as words
MATCH (w:Word)<-[:MENTIONED]-(a:Article)-[:MENTIONED]->(w2:Word)
WHERE w.name IN words AND w2.name IN words
RETURN a, w, w2

,但不适用于一个单词列表.如何使它处理任意数量的单词?有更好的方法吗?

but does not work with word list of one. How can I make it handle any number of words? Is there a better way to do this?

推荐答案

是.我可以想到两种方法:

Yes. There are two approaches I can think of:

  1. 查找包含某些单词子集的所有文章,然后仅返回提及的单词数是您在单词列表中提供的单词数的文章.

  1. Finding all articles that contain some subset of those words, and then returning only articles where the number of words mentioned is the number of words you supplied in your wordlist.

获取给定单词列表的:Word节点,然后获取文章中提及所有单词的文章.

Getting the :Word nodes for the given list of words, and then getting articles where all words are mentioned in the article.

下面是一个示例图,用于对其进行测试:

Here's an example graph to test this on:

MERGE (a1:Article {name:'a1'}), 
      (a2:Article {name:'a2'}), 
      (a3:Article {name:'a3'})
MERGE (w1:Word{name:'orange'}), 
      (w2:Word{name:'apple'}), 
      (w3:Word{name:'pineapple'}), 
      (w4:Word{name:'banana'})
MERGE (a1)-[:MENTIONED]->(w1), 
      (a1)-[:MENTIONED]->(w2), 
      (a1)-[:MENTIONED]->(w3), 
      (a1)-[:MENTIONED]->(w4),
      (a2)-[:MENTIONED]->(w1), 
      (a2)-[:MENTIONED]->(w4),
      (a3)-[:MENTIONED]->(w1), 
      (a3)-[:MENTIONED]->(w2),
      (a3)-[:MENTIONED]->(w3)

方法1,将词表大小与文章中提到的词数进行比较,如下所示:

Approach 1, comparing the wordlist size to the number of words mentioned in the article, looks like this:

WITH ["orange", "apple"] as words
MATCH (word:Word)<-[:MENTIONED]-(article:Article)
WHERE word.name IN words
WITH words, article, COUNT(word) as wordCount
WHERE wordCount = SIZE(words)
RETURN article

这仅在文章和提到的单词之间只有一种:MENTIONED关系时才有效,无论该单词被提及了多少次.

This only works if there is ever only one :MENTIONED relationship between an article and a mentioned word, no matter how many times that word is mentioned.

方法2在:Words集合上使用ALL()以确保我们与提到所有单词的文章相匹配:

Approach 2 is using ALL() on the collection of :Words to ensure that we match on an article where all words are mentioned:

WITH ["orange", "apple"] as words
MATCH (word:Word) 
WHERE word.name in words
WITH COLLECT(word) as words
MATCH (article:Article)
WHERE ALL (word in words WHERE (word)<-[:MENTIONED]-(article))
RETURN article

您可以尝试将PROFILE与每个参数一起使用,以确定哪种数据最适合您的数据集.

You can try using PROFILE with each of these to figure out which works best with your data set.

这篇关于Neo4j Cypher:在一组匹配的节点之间查找公共节点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆