Ограничить и упорядочить собранные узлы, ранжированные по их общим уникальным вхождениям - PullRequest
0 голосов
/ 24 января 2019

Я «играю» с neo4j в течение нескольких недель. Это удивительно, и я постепенно начинаю разбираться с этим, и теперь у меня есть подходящий вариант использования.

Я сдаю экзамены по садоводству через пару недель. Мне нужно знать достаточное количество растений по их характеристикам или использованию, и цель графика - найти наименьшее количество растений для изучения (некоторые относятся к нескольким вопросам)

На моем графике эти характеристики являются (Feature) узлами

На экзамене сказано 30 (вопрос) с.

Каждый (Вопрос) имеет отношение [FIND] -> к (FeatureSet) с {числом} того, сколько примеров различных растений ему требуется.

(FeatureSet) [ВКЛЮЧАЕТ] -> один или несколько (Feature) s - такие вещи, как «вечнозеленый», «дерево», «кустарник». 'луковица', 'зимнее цветение', 'патио'

(т.е. назовите 10 кустов, 5 вечнозеленых кустарников, 5 растений для горшка зимой)

Я создаю связь (Завод) - [ОСОБЕННОСТИ] -> (Элемент) для каждой функции, имеющейся у растений в моей базе данных.

Я могу выполнить запрос, показывающий мне ВСЕ растения, соответствующие ВСЕМ объектам в наборе объектов, указанном в вопросе

//SIMPLE RESULTS
MATCH (q:Question)-[find:FIND]->(fs:FeatureSet)

WITH fs, q, find.number as qNum
//GET ALL THE FEATURE SETS
MATCH (fInSet:Feature)<-[inc:INCLUDES]-(fs)
WITH fs, q , qNum, COLLECT(fInSet.feature) as fInSetList
MATCH (p:Plant)-[:FEATURES]->(fOfPlant:Feature)
WHERE fOfPlant.feature IN fInSetList
//Only plants matching all features
WITH fs, q , qNum, p, fInSetList, size(fInSetList) as inputCnt, count(DISTINCT fOfPlant) as cnt
WHERE cnt = inputCnt

RETURN
q.id,
'Give ' + qNum + ' examples of ' + q.q as Question,
fInSetList as plantFeaturesReqd,
COLLECT(
p.name
)
as plantsFound
ORDER BY q.id
q.id    Question    plantFeaturesReqd   plantsFound
"1" "Give 1 examples of Evergreen Shrubs"   ["evergreen", "shrub"]  ["Rhododendron"]
"2" "Give 3 examples of Shrubs" ["shrub"]   ["Cornus", "Wych Hazel", "Buddleja", "Rhododendron"]
"3" "Give 1 examples of Deciduous Shrubs"   ["deciduous", "shrub"]  ["Cornus", "Wych Hazel"]

Я могу изменить свое утверждение RETURN, чтобы узнать, сколько раз растение появляется в общем наборе результатов, что дает ему вес при принятии решения, изучать его или нет:

RETURN
DISTINCT p.name as dName,
count(p.name) as dCount
ORDER BY dCount DESC
"Wych Hazel"    2
"Cornus"    2
"Rhododendron"  2
"Buddleja"  1

Я вижу по результатам, что я могу уйти, не изучив Буддлею.

Я хочу достичь чего-то вроде:

q.id    Question    plantFeaturesReqd   plantsFound
"1" "Give 1 examples of Evergreen Shrubs"   ["evergreen", "shrub"]  [{p:"Rhododendron", w:2}]
"2" "Give 3 examples of Shrubs" ["shrub"]   [{p:"Cornus",w:2}, {p:"Wych Hazel",w:2}, {p:"Rhododendron", w:2}, {p:"Buddleja",w:1}]
"3" "Give 1 examples of Deciduous Shrubs"   ["deciduous", "shrub"]  [{p:"Cornus",w:2}, {p:"Wych Hazel",w:2}]

и затем получите правильный [НАЙТИ {число}] растений для каждого вопроса, упорядоченный по весу {w}.

Существует более одного варианта с таким же весом, который я мог бы выучить для q3 (1 лиственный кустарник), но мне нужно только узнать о его лиственных свойствах, так как я уже узнаю, что это куст из q2 (2 куста).

Точно так же, если бы мне нужно было выучить только 2 куста, это было бы столкновением между отказом от Cornus или Wych Hazel с тем же весом.

Так что я бы хотел (на более позднем этапе) отрегулировать этот вес по другим причинам (например, я могу легче запомнить латинское имя, или мне просто нравится!). Объединение этих предпочтений также должно исключать «нарушение» выбора для других вопросов.

Очевидно, что с большим количеством вопросов (наборов функций) и тысячами вариантов выбора растений это имеет больше смысла на практике.

SVG графика (извините, я не могу загрузить SVG здесь и png плохой)

CREATE.cypher

CREATE 
  (`0` :Feature {feature:'deciduous'}) ,
  (`1` :FeatureSet ) ,
  (`2` :Feature {feature:'shrub'}) ,
  (`3` :Feature {feature:'evergreen'}) ,
  (`5` :FeatureSet ) ,
  (`9` :Plant {name:'Rhododendron'}) ,
  (`13` :Question {id:'1',q:'Evergreen Shrubs'}) ,
  (`14` :Feature {feature:'semi-evergreen'}) ,
  (`15` :Plant {name:'Buddleja'}) ,
  (`16` :Question {id:'2',q:'Shrubs'}) ,
  (`17` :FeatureSet ) ,
  (`18` :Question {id:'3',q:'Deciduous Shrubs'}) ,
  (`19` :Plant {name:'Cornus'}) ,
  (`29` :Feature {feature:'winter-interest-flowers'}) ,
  (`30` :Plant {name:'Wych Hazel'}) ,
  (`1`)-[:`INCLUDES` ]->(`0`),
  (`1`)-[:`INCLUDES` ]->(`2`),
  (`5`)-[:`INCLUDES` ]->(`3`),
  (`5`)-[:`INCLUDES` ]->(`2`),
  (`9`)-[:`FEATURES` ]->(`2`),
  (`9`)-[:`FEATURES` ]->(`3`),
  (`13`)-[:`FIND` {number:1}]->(`5`),
  (`15`)-[:`FEATURES` ]->(`14`),
  (`15`)-[:`FEATURES` ]->(`2`),
  (`17`)-[:`INCLUDES` ]->(`2`),
  (`16`)-[:`FIND` {number:3}]->(`17`),
  (`18`)-[:`FIND` {number:1}]->(`1`),
  (`19`)-[:`FEATURES` ]->(`0`),
  (`19`)-[:`FEATURES` ]->(`2`),
  (`30`)-[:`FEATURES` ]->(`29`),
  (`30`)-[:`FEATURES` ]->(`0`),
  (`30`)-[:`FEATURES` ]->(`2`)

ARROWS.html

<ul class="graph-diagram-markup" data-internal-scale="1" data-external-scale="1">
  <li class="node" data-node-id="0" data-x="-162.05996704101562" data-y="-608.8465919494629">
    <span class="caption">Feature</span><dl class="properties"><dt>feature</dt><dd>deciduous</dd></dl></li>
  <li class="node" data-node-id="1" data-x="-547.4232482910156" data-y="75.07541275024414">
    <span class="caption">FeatureSet</span>
  </li>
  <li class="node" data-node-id="2" data-x="-1049.3427429199219" data-y="-608.8465919494629">
    <span class="caption">Feature</span><dl class="properties"><dt>feature</dt><dd>shrub</dd></dl></li>
  <li class="node" data-node-id="3" data-x="-2028.5903301239014" data-y="-608.8465919494629">
    <span class="caption">Feature</span><dl class="properties"><dt>feature</dt><dd>evergreen</dd></dl></li>
  <li class="node" data-node-id="5" data-x="-1586.3723907470703" data-y="44.78205490112305">
    <span class="caption">FeatureSet</span>
  </li>
  <li class="node" data-node-id="9" data-x="-1549.8740997314453" data-y="-1406.8265972137451">
    <span class="caption">Plant</span><dl class="properties"><dt>name</dt><dd>Rhododendron</dd></dl></li>
  <li class="node" data-node-id="13" data-x="-1586.3723907470703" data-y="582.2714309692383">
    <span class="caption">Question</span><dl class="properties"><dt>id</dt><dd>1</dd><dt>q</dt><dd>Evergreen Shrubs</dd></dl></li>
  <li class="node" data-node-id="14" data-x="-2757.7551736831665" data-y="-641.2539367675781">
    <span class="caption">Feature</span><dl class="properties"><dt>feature</dt><dd>semi-evergreen</dd></dl></li>
  <li class="node" data-node-id="15" data-x="-2083.2289657592773" data-y="-1406.8265972137451">
    <span class="caption">Plant</span><dl class="properties"><dt>name</dt><dd>Buddleja</dd></dl></li>
  <li class="node" data-node-id="16" data-x="-1106.6406211853027" data-y="561.1691665649414">
    <span class="caption">Question</span><dl class="properties"><dt>id</dt><dd>2</dd><dt>q</dt><dd>Shrubs</dd></dl></li>
  <li class="node" data-node-id="17" data-x="-1106.6406211853027" data-y="44.78205490112305">
    <span class="caption">FeatureSet</span>
  </li>
  <li class="node" data-node-id="18" data-x="-547.4232482910156" data-y="561.1691665649414">
    <span class="caption">Question</span><dl class="properties"><dt>id</dt><dd>3</dd><dt>q</dt><dd>Deciduous Shrubs</dd></dl></li>
  <li class="node" data-node-id="19" data-x="-677.7754373550415" data-y="-1343.9512340724468">
    <span class="caption">Plant</span><dl class="properties"><dt>name</dt><dd>Cornus</dd></dl></li>
  <li class="node" data-node-id="29" data-x="573.2279720306396" data-y="-608.8465919494629">
    <span class="caption">Feature</span><dl class="properties"><dt>feature</dt><dd>winter-interest-flowers</dd></dl></li>
  <li class="node" data-node-id="30" data-x="164.77948760986328" data-y="-1343.9512340724468">
    <span class="caption">Plant</span><dl class="properties"><dt>name</dt><dd>Wych Hazel</dd></dl></li>
  <li class="relationship" data-from="1" data-to="0">
    <span class="type">INCLUDES</span>
  </li>
  <li class="relationship" data-from="1" data-to="2">
    <span class="type">INCLUDES</span>
  </li>
  <li class="relationship" data-from="5" data-to="3">
    <span class="type">INCLUDES</span>
  </li>
  <li class="relationship" data-from="5" data-to="2">
    <span class="type">INCLUDES</span>
  </li>
  <li class="relationship" data-from="9" data-to="2">
    <span class="type">FEATURES</span>
  </li>
  <li class="relationship" data-from="9" data-to="3">
    <span class="type">FEATURES</span>
  </li>
  <li class="relationship" data-from="13" data-to="5">
    <span class="type">FIND</span><dl class="properties"><dt>number</dt><dd>1</dd></dl></li>
  <li class="relationship" data-from="15" data-to="14">
    <span class="type">FEATURES</span>
  </li>
  <li class="relationship" data-from="15" data-to="2">
    <span class="type">FEATURES</span>
  </li>
  <li class="relationship" data-from="17" data-to="2">
    <span class="type">INCLUDES</span>
  </li>
  <li class="relationship" data-from="16" data-to="17">
    <span class="type">FIND</span><dl class="properties"><dt>number</dt><dd>3</dd></dl></li>
  <li class="relationship" data-from="18" data-to="1">
    <span class="type">FIND</span><dl class="properties"><dt>number</dt><dd>1</dd></dl></li>
  <li class="relationship" data-from="19" data-to="0">
    <span class="type">FEATURES</span>
  </li>
  <li class="relationship" data-from="19" data-to="2">
    <span class="type">FEATURES</span>
  </li>
  <li class="relationship" data-from="30" data-to="29">
    <span class="type">FEATURES</span>
  </li>
  <li class="relationship" data-from="30" data-to="0">
    <span class="type">FEATURES</span>
  </li>
  <li class="relationship" data-from="30" data-to="2">
    <span class="type">FEATURES</span>
  </li>
</ul>

Обновлено

Я обновил это с помощью более простого примера, теперь содержащего ограниченный сценарий создания, разметку стрелок и ссылку на SVG.

Ответы [ 2 ]

0 голосов
/ 26 января 2019

Ну, несколько часов спустя ....

Этот запрос дает мне результат, на который я хочу ответить по существу.

РЕДАКТИРОВАТЬ: К сожалению, после дальнейшего тестирования на более широком наборе данных сортировка по-прежнему не работает, как ожидалось, поэтому этот ответ не является полным.

Теперь я могу работать над настройкой альтернативных вариантов для растений с равными весами на основе моих предпочтений (пока я нашел только способы сделать это неправильно, и в настоящее время он не обрабатывает эти случаи).

//SIMPLE RESULTS
MATCH (q:Question)-[find:FIND]->(fs:FeatureSet)

WITH fs, q, find.number as qNum
//GET ALL THE FEATURE SETS
MATCH (fInSet:Feature)<-[inc:INCLUDES]-(fs)
WITH fs, q , qNum, COLLECT(fInSet.feature) as fInSetList
MATCH (p:Plant)-[:FEATURES]->(fOfPlant:Feature)
WHERE fOfPlant.feature IN fInSetList
//Only plants matching all features
WITH fs, q , qNum, p, fInSetList, size(fInSetList) as inputCnt, count(DISTINCT fOfPlant) as cnt, 
collect(p.name) as pALL //** THIS IS IMPORTANT, BUT I DON'T UNDERSTAND QUITE WHY **//
WHERE cnt = inputCnt
WITH *, count(p) as pCnt
ORDER BY pCnt //** THIS RANKS BY WEIGHT BASED ON TOTAL OCCURRENCES **//
RETURN
q.id,
'Give ' + qNum + ' examples of ' + q.q as Question,
fInSetList as plantFeaturesReqd,
COLLECT(
p.name
)[0..qNum]  //** THIS LIMITS TO NUMBER REQUIRED PER QUESTION **//
as plantsFound
ORDER BY q.id
q.id    Question    plantFeaturesReqd   plantsFound
"1" "Give 1 examples of Evergreen Shrubs"   ["evergreen", "shrub"]  ["Rhododendron"]
"2" "Give 3 examples of Shrubs" ["shrub"]   ["Cornus", "Rhododendron", "Wych Hazel"]
"3" "Give 1 examples of Deciduous Shrubs"   ["deciduous", "shrub"]  ["Cornus"]
0 голосов
/ 26 января 2019

Если я правильно понял, вы почти у цели, пропали только две вещи.

  1. отсортируйте по весу, чтобы затем группа сохранила этот вес
  2. создавать и собирать карты для каждого вопроса.собирать ({имя: фамилия, вес: вес})

    • Почему номер вопроса на НАЙТИ?

Пожалуйста, попробуйте этот запрос:

MATCH (q:Question)-[find:FIND]->(fs:FeatureSet)

WITH fs, q, find.number as qNum
//GET ALL THE FEATURE SETS
MATCH (fInSet:Feature)<-[inc:INCLUDES]-(fs)
WITH fs, q , qNum, COLLECT(fInSet.feature) as fInSetList
MATCH (p:Plant)-[:FEATURES]->(fOfPlant:Feature)
     WHERE fOfPlant.feature IN fInSetList
//Only plants matching all features
WITH fs, q , qNum, p, fInSetList, 
     size(fInSetList) as inputCnt, count(DISTINCT fOfPlant) as cnt
     WHERE cnt = inputCnt
WITH *
// order by cnt == weight
ORDER BY cnt DESC
RETURN
q.id,
'Give ' + qNum + ' examples of ' + q.q as Question,
fInSetList as plantFeaturesReqd,
// collect maps
COLLECT({plant: p.name, weight: cnt}) as plantsFound
ORDER BY q.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...