2017-02-18 13 views
1

У меня есть следующий запрос: CypherNeo4j Cypher запрос и комплекс сортировки

MATCH (t:Tenant) WHERE ID(t) in {tenantIds} 
OR t.isPublic 
WITH COLLECT(t) as tenants 
MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) 
WHERE id(parentD) = {decisionId} 
AND (not (parentD)-[:BELONGS_TO]-(:Tenant) 
    OR any(t in tenants WHERE (parentD)-[:BELONGS_TO]-(t))) 
AND (not (childD)-[:BELONGS_TO]-(:Tenant) 
    OR any(t in tenants WHERE (childD)-[:BELONGS_TO]-(t))) 
MATCH (childD)<-[:SET_FOR]-(filterValue630:Value)-[:SET_ON]->(filterCharacteristic630:Characteristic) 
WHERE id(filterCharacteristic630) = 630 
WITH filterValue630, childD, ru, u 
WHERE (filterValue630.value <= 799621200000) 
OPTIONAL MATCH (childD)<-[:SET_FOR]->(sortValue631:Value)-[:SET_ON]->(sortCharacteristic631:Characteristic) 
WHERE id(sortCharacteristic631) = 631 
RETURN ru, u, childD AS decision, 
[ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
| {entityId: id(entity), types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
[ (parentD)<-[:DEFINED_BY]-(c1:Criterion)<-[:VOTED_ON]-(vg1:VoteGroup)-[:VOTED_FOR]->(childD) 
| {criterionId: id(c1), weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
[ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[:SET_ON]-(v1:Value)-[:SET_FOR]->(childD) 
| {characteristicId: id(ch1), value: v1.value, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics 
ORDER BY sortValue631.value ASC, childD.createDate DESC 
SKIP 0 LIMIT 100 

в результате этого выполнения запроса я получаю 15 записей, где каждый из них правильно содержит густонаселенные commentGroups, weightedCriteria и valuedCharacteristics коллекции.

Но когда я меняю запрос к следующему один (я добавляю условие сортировки по весу критериев):

MATCH (t:Tenant) 
WHERE ID(t) in {tenantIds} 
OR t.isPublic 
WITH COLLECT(t) as tenants 
MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) 
WHERE id(parentD) = {decisionId} 
AND (not (parentD)-[:BELONGS_TO]-(:Tenant) 
    OR any(t in tenants WHERE (parentD)-[:BELONGS_TO]-(t))) 
AND (not (childD)-[:BELONGS_TO]-(:Tenant) 
    OR any(t in tenants WHERE (childD)-[:BELONGS_TO]-(t))) 
MATCH (childD)<-[:SET_FOR]-(filterValue630:Value)-[:SET_ON]->(filterCharacteristic630:Characteristic) 
WHERE id(filterCharacteristic630) = 630 
WITH filterValue630, childD, ru, u 
WHERE (filterValue630.value <= 799621200000) 
OPTIONAL MATCH (childD)<-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]->(c:Criterion) 
WHERE id(c) IN {criteriaIds} 
WITH c, childD, ru, u, (vg.avgVotesWeight * (CASE WHEN c IS NOT NULL THEN coalesce({criteriaCoefficients}[toString(id(c))], 1.0) ELSE 1.0 END)) as weight, vg.totalVotes as totalVotes 
OPTIONAL MATCH (childD)<-[:SET_FOR]->(sortValue631:Value)-[:SET_ON]->(sortCharacteristic631:Characteristic) 
WHERE id(sortCharacteristic631) = 631 
RETURN ru, u, childD AS decision, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes, sortValue631, 
[ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
| {entityId: id(entity), types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
[ (parentD)<-[:DEFINED_BY]-(c1:Criterion)<-[:VOTED_ON]-(vg1:VoteGroup)-[:VOTED_FOR]->(childD) 
| {criterionId: id(c1), weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
[ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[:SET_ON]-(v1:Value)-[:SET_FOR]->(childD) 
| {characteristicId: id(ch1), value: v1.value, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics 
ORDER BY weight DESC, totalVotes ASC, sortValue631.value ASC, childD.createDate DESC 
SKIP 0 LIMIT 100 

запрос работает без ошибок и возвращает тот же результирующий набор из 15 записей, но commentGroups, weightedCriteria и valuedCharacteristics коллекции только заселена, где weight > 0 остальные из них null

Это неправильно и, как ожидалось. Коллекции commentGroups, weightedCriteria и valuedCharacteristics должны заполняться для всех записей в моем результирующем наборе, как это было после первого выполнения запроса.

Прямо сейчас я не понимаю, почему следующая часть нового Cypher запроса предотвращает правильное население указанных коллекций:

OPTIONAL MATCH (childD)<-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]->(c:Criterion) 
WHERE id(c) IN {criteriaIds} 
WITH c, childD, ru, u, (vg.avgVotesWeight * (CASE WHEN c IS NOT NULL THEN coalesce({criteriaCoefficients}[toString(id(c))], 1.0) ELSE 1.0 END)) as weight, vg.totalVotes as totalVotes 

Что я делаю неправильно в новом запросе и как это исправить?

ОБНОВЛЕНО

Это запрос, который производит вопрос:

MATCH (t:Tenant) WHERE ID(t) in [] 
    OR t.isPublic 
    WITH COLLECT(t) as tenants 
    MATCH (parentD)-[:CONTAINS]->(childD:Decision)-[ru:CREATED_BY]->(u:User) 
    WHERE id(parentD) = 60565 
    AND (not (parentD)-[:BELONGS_TO]-(:Tenant) 
     OR any(t in tenants WHERE (parentD)-[:BELONGS_TO]-(t))) 
    AND (not (childD)-[:BELONGS_TO]-(:Tenant) 
     OR any(t in tenants WHERE (childD)-[:BELONGS_TO]-(t))) 
    MATCH (childD)<-[:SET_FOR]-(filterValue60639:Value)-[:SET_ON]->(filterCharacteristic60639:Characteristic) 
    WHERE id(filterCharacteristic60639) = 60639 
    WITH filterValue60639, childD, ru, u 
    WHERE (filterValue60639.value <= 799621200000) 
    OPTIONAL MATCH (childD)<-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]->(c:Criterion) 
    WHERE id(c) IN [60581, 60575] 
    WITH childD, ru, u, vg.avgVotesWeight as weight, vg.totalVotes as totalVotes 
    OPTIONAL MATCH (childD)<-[:SET_FOR]->(sortValue60640:Value)-[:SET_ON]->(sortCharacteristic60640:Characteristic) 
    WHERE id(sortCharacteristic60640) = 60640 
    RETURN ru, u, childD AS decision, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes, sortValue60640, 
    [ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
    | {entityId: id(entity), types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
    [ (parentD)<-[:DEFINED_BY]-(c1:Criterion)<-[:VOTED_ON]-(vg1:VoteGroup)-[:VOTED_FOR]->(childD) 
    | {criterionId: id(c1), weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
    [ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[:SET_ON]-(v1:Value)-[:SET_FOR]->(childD) 
    | {characteristicId: id(ch1), value: v1.value, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics 
    ORDER BY weight DESC, totalVotes ASC, sortValue60640.value ASC, childD.createDate DESC 
    SKIP 0 LIMIT 100 

по какой-то причине

OPTIONAL MATCH (childD)<-[:VOTED_FOR]-(vg:VoteGroup)-[:VOTED_ON]->(c:Criterion) 
    WHERE id(c) IN [60581, 60575] 

предотвращает commentGroups, weightedCriteria и valuedCharacteristics сбора населения для всех childD что не соответствуют этому выражению .. Как t o исправить это?

enter image description here

+1

было бы хорошо, если вы можете раздеться запрос дальше и обеспечить минимальный набор данных для демонстрации его и поделитесь им через http://console.neo4j.org. –

+0

Я не могу найти информацию о том, как сбрасывать базу данных в скрипт Cypher под платформой Windows, чтобы загрузить ее на console.neo4j.org – alexanoid

+0

@StefanArmbruster Я обновил свой вопрос с дампа моей тестовой базы данных.К сожалению, я не нашел способ загрузить его на console.neo4j.org, поэтому я сбросил мою базу данных в файловую систему. – alexanoid

ответ

2

Хорошо, это довольно странно. Я нашел что-то, что должно сработать, хотя на данный момент я не могу понять, почему он работает, просто он предполагает вычисление веса и totalVotes до вашего возвращения.

Возьмите первую строку RETURN, и заменить его в этом, который включает в себя с пунктом первого, который будет вычислить вес и totalVotes, а затем выполнить обратное:

WITH ru, u, childD, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes, sortValue60640 
RETURN ru, u, childD AS decision, weight, totalVotes, sortValue60640, 

Еще одна вещь отметить, вы можете сохранить некоторые ненужные операции, выполняя свой заказ, SKIP, и ПРЕДЕЛ операции, прежде чем выполнять геометрические шаблоны постижений:

WITH ru, u, childD, toFloat(sum(weight)) as weight, toInt(sum(totalVotes)) as totalVotes, sortValue60640 
ORDER BY weight DESC, totalVotes ASC, sortValue60640.value ASC, childD.createDate DESC 
    SKIP 0 LIMIT 100 
RETURN ru, u, childD AS decision, weight, totalVotes, sortValue60640, 
    [ (parentD)<-[:DEFINED_BY]-(entity)<-[:COMMENTED_ON]-(comg:CommentGroup)-[:COMMENTED_FOR]->(childD) 
    | {entityId: id(entity), types: labels(entity), totalComments: toInt(comg.totalComments)} ] AS commentGroups, 
    [ (parentD)<-[:DEFINED_BY]-(c1:Criterion)<-[:VOTED_ON]-(vg1:VoteGroup)-[:VOTED_FOR]->(childD) 
    | {criterionId: id(c1), weight: vg1.avgVotesWeight, totalVotes: toInt(vg1.totalVotes)} ] AS weightedCriteria, 
    [ (parentD)<-[:DEFINED_BY]-(ch1:Characteristic)<-[:SET_ON]-(v1:Value)-[:SET_FOR]->(childD) 
    | {characteristicId: id(ch1), value: v1.value, valueType: ch1.valueType, visualMode: ch1.visualMode} ] AS valuedCharacteristics 
+0

Большое спасибо за вашу помощь! Все работает как шарм! – alexanoid