2017-01-18 3 views
1

У меня есть документ - [: Содержит] -> Ключевое слово. Я хотел бы получить все документы, имеющие указанный список ключевых слов. До сих пор мне удалось это сделать:Neo4j - Получить узел, содержащий список детей

Match (d:document)-[:CONTAINS]->(k1:keyword {keyword:"key1"}) 
WITH d,k1 
MATCH (d)-[CONTAINS]->(k2:keyword {keyword:"key2"}) 
return d, k1, k2 

Этот запрос возвращает все документы, содержащие как «key1» и «key2» в качестве ключевых слов. Проблема в том, что запрос должен быть изменен в зависимости от количества ключевых слов, которые я ищу. Можно ли использовать список в качестве параметра поиска и изменить список, а не сам запрос?

+1

Вы хотите, чтобы вы использовали ':' для вашего: CONTAINS отношения, иначе это переменная вместо типа. – InverseFalcon

+0

Кроме того, вы хотите, чтобы документы, содержащие одно или несколько ключевых слов в списке, или должны содержать все ключевые слова в списке? – InverseFalcon

+0

В идеале я мог бы вернуть документы, содержащие одно или несколько ключевых слов, и упорядочить их в порядке убывания в соответствии с количеством совпадений. Другой (менее желательный) вариант - вернуть документы, содержащие ВСЕ ключевые слова. – ganninu93

ответ

2

[ОБНОВЛЕНО]

Запрос, как это должно работать:

MATCH (d:document)-[:CONTAINS]->(k:keyword) 
WHERE k.keyword IN {keywords} 
RETURN d, COUNT(k) AS cnt 
ORDER BY cnt DESC; 

В этом запросе keywords предполагается совокупность ключевых слов строк, передаваемых в качестве parameter. Я также предположил, что CONTAINS является типом отношений, поэтому я добавил префикс :.

Для повышения производительности вы можете создать индекс в свойстве keyword метки узла keyword. (На практике вам, вероятно, следует присвоить ярлыку и свойства другим именам ...).

CREATE INDEX ON :keyword(keyword); 

После этого, возможно, придется изменить первоначальный запрос, чтобы задобрить Cypher планировщик в использовании индекс:

MATCH (d:document)-[CONTAINS]->(k:keyword) 
USING INDEX k:keyword(keyword) 
WHERE k.keyword IN {keywords} 
RETURN d, COUNT(k) AS cnt 
ORDER BY cnt DESC; 
+0

Это вернет документы, в которых есть ключевое слово из списка ключевых слов, но оно не будет возвращать документы, содержащие все ключевые слова в списке. Учитывая формулировку вопроса, есть хороший шанс, что они ищут запрос, который соответствует всем ключевым словам в списке. – InverseFalcon

+0

Спасибо, что указали мне в правильном направлении, однако предлагаемые вами документы возвращают документы, содержащие ЛЮБОЕ из ключевых слов, а не все из них. Я попытался добавить _WITH d, k, count (k) AS matchcount_ после того, как получить число совпадающих ключевых слов на документ, но это всегда возвращает 1 – ganninu93

+0

См. Мой обновленный ответ. Он возвращает документы с любыми совпадающими ключевыми словами, упорядоченными по убыванию количества совпадающих ключевых слов. – cybersam

0

В дополнение к тому, что @cybersam предложил это решение возвращает только те документы, которые соответствие всем ключевым словам.

MATCH (d:document)-[:CONTAINS]->(k:keyword) 
WITH d,k, ["key1", "key2"] AS input 
WHERE k.keyword IN input 
WITH d, input, COUNT(k) AS cnt 
WHERE cnt=size(input) 
return d, cnt; 
Смежные вопросы