Запрос Neo4j, объединяющий данные из Elasticsearch для временного графика - PullRequest
0 голосов
/ 28 апреля 2020

Neo4j и Cypher gurus,

Я использую Neo4j, Elasticsearch и Spring Data Neo4j. У меня есть узлы сущностей, которые связаны друг с другом. На связи есть поле подсчета, которое является общим числом отношений между двумя объектами. Я использую следующий Cypher, чтобы вернуть 50 верхних отношений для сущности:

MATCH (e1:Entity)-[r1:RELATED_TO]-(e2:Entity)
WHERE e1.uuid = '<ENTITY_ID>'
RETURN e1,r1,e2
ORDER BY r1.count DESC
LIMIT 50

Теперь я хотел бы визуализировать график, основанный на времени для сущности, возвращая 50 верхних связей для сущности. последняя неделя (последний месяц и т. д. c). Я не храню данные временных рядов в Neo4j, только общее количество для отношений. Данные временного ряда хранятся в индексе Elasticsearch в следующем формате.

Date, entityOrRelationshipId, startId, endId, type

Каждый раз, когда обновляется связь, в индекс вставляется строка с указанием datetime, relationsId и entityId.

Количество связей можно искать и объединять с помощью следующего запроса Elasticsearch:

GET localhost:9200/trends/_search

{
    "size": 0,
    "query": {
        "bool": {
            "must": [
                {
                    "term": {
                        "type": "RELATIONSHIP"
                    }
                },
                {
                    "range": {
                        "date": {
                            "gte": "2020-04-01T00:00:00.000+00:00",
                            "lt": "2020-04-28T00:00:00.000+00:00"
                        }
                    }
                },
                {
                    "bool": {
                        "should": [
                            { "term": { "startId": "<ENTITY_ID>"} },
                            { "term": { "endId": "<ENTITY_ID>" } }
                        ]
                    }
                }
            ]
        }
    },
    "aggs": {
        "my_rels": {
            "terms": {
                "field": "entityOrRelationshipId",
                "size": 50
            }
        }
    }
} 

Это приводит к следующим результатам с количеством (doc_count) для каждого идентификатора отношения для определенного диапазона дат :

{
    "took": 5,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 2273,
        "max_score": 0.0,
        "hits": []
    },
    "aggregations": {
        "my_rels": {
            "doc_count_error_upper_bound": 0,
            "sum_other_doc_count": 145,
            "buckets": [
                {
                    "key": "2fa94be4-828b-4a20-b5f8-4965d5516149",
                    "doc_count": 303
                },
                {
                    "key": "74fb5f46-a6e8-41a8-bd11-cb374324b285",
                    "doc_count": 197
                },
                {
                    "key": "dc57fdcf-ea88-4808-9310-4e09d368e743",
                    "doc_count": 178
                },
                {
                    "key": "c4fbda1f-717e-4422-bc10-66ca6a6f39d7",
                    "doc_count": 79
                },
                etc.

            ]
        }
    }
}

Используя библиотеку Neo4J APO C, как мне объединить результаты подсчета Elasticsearch в мой запрос Cypher без необходимости сохранять значения счетчика в Neo4J?

Любая помощь будет высоко ценится.

1 Ответ

0 голосов
/ 28 апреля 2020

Предполагая, что:

  • RELATED_TO имеют свойство uuid для идентификатора отношения и
  • идентификатор Entity и "корзины" список передается в запрос как параметры entityId и buckets, это должно работать:

    UNWIND $buckets AS b
    MATCH (e1:Entity)-[r1:RELATED_TO]-(e2)
    WHERE e1.uuid = $entityId AND r1.uuid = b.key
    RETURN e1, r1, e2, b.doc_count AS count
    ORDER BY count DESC
    

Предложение LIMIT не требуется , поскольку количество строк результата будет определяться размером списка buckets.

...