Elasticsearch Vs MongoDB Aggregation - Сравнение разработки с примером - PullRequest
0 голосов
/ 14 октября 2019

Я конвертирую MongoDB Запрос в Elasticsearch на NodeJS платформе. Во время разработки я столкнулся с некоторыми трудностями с группировкой и фильтрацией данных (получение вложенных объектов, таких как hit.hits._source ) в Elasticsearch Query, как мы это делали в MongoDB Query.

Пример: -

UserModel.aggregate([
    {
        $match: {
            uId: req.body.uId, timestamp: { $gte: req.body.date, $lte: new Date() }
        },
    },
    {
        $group: {
            _id: "$eId",
            location: {
                $push: {
                    time: "$timestamp", lat: "$lat"
                }
            },
            timestamp: {
                $push: "$timestamp"
            },
            testId: { $first: "$testId" },
        }
    },
    {
        $project: {
            eId: 1, location: 1, testId: 1, max: { $max: "$timestamp" }
        }
    },
    { $unwind: { path: "$location", preserveNullAndEmptyArrays: true } },
    {
        $redact: {
            $cond: {
                if: { $eq: ["$location.time", "$max"] },
                then: "$$DESCEND",
                else: "$$PRUNE"
            }
        }
    },
    {
        $project: {
            eId: 1, latitude: "$location.lat", testId: 1
        }
    },
]).exec(function (err, result) {
    console.log(result)
});

Каким будет эквивалентный запрос в Elasticsearch? Я ищу решение с группировкой, раскруткой и проецированием (концепции MongoDB в Elasticsearch) необходимых данных с минимальным вложенным ответом. Заранее спасибо.

РЕДАКТИРОВАТЬ: -

Добавление документа Elasticsearch: -

{
          "timestamp": "2019-10-08T:02:50:15.54Z",
          "status" : 1,
          "eId": "5d5d7ce0c89852e7bad4a407",
          "location": [
            2.000,
            34.5664111801
          ],
          "zId": "5d5d7ce0c89852e7bad4a4ef"
},
{
          "timestamp": "2019-10-09T:02:50:15.54Z",
          "status" : 1,
          "eId": "5d5d7ce0c89852e7bad4a408",
          "location": [
            2.100,
            35.5664111801
          ],
          "zId": "5d5d7ce0c89852e7bad4a4ef"
},
{
          "timestamp": "2019-10-09T:03:50:15.54Z",
          "status" : 1,
          "eId": "5d5d7ce0c89852e7bad4a407",
          "location": [
            4.100,
            35.5664111801
          ],
          "zId": "5d5d7ce0c89852e7bad4a4ef"
},
{
          "timestamp": "2019-10-09T:03:40:15.54Z",
          "status" : 1,
          "eId": "5d5d7ce0c89852e7bad4a407",
          "location": [
            2.100,
            35.5664111801
          ],
          "zId": "5d5d7ce0c89852e7bad4a4e1"
},
{
          "timestamp": "2019-10-10T:03:40:15.54Z",
          "status" : 1,
          "eId": "5d5d7ce0c89852e7bad4a407",
          "location": [
            3.100,
            35.5664111801
          ],
          "zId": "5d5d7ce0c89852e7bad4a4e1"
}
  1. Соответствовать со статусом = 1 и группировать по eId
  2. С этимрезультаты, сгруппированные по отметке времени и получим максимальное значение отметки времени

Ожидаемый результат: -

[
        {
            "_id": "5d5d7ce0c89852e7bad4a407",
            "max": "2019-10-10T:03:40:15.54Z", // max timestamp
            "zId": [
                "5d5d7ce0c89852e7bad4a4e1",
                "5d5d7ce0c89852e7bad4a4ef"
            ]
        },
        {
            "_id": "5d5d7ce0c89852e7bad4a408",
            "max": "2019-10-09T:02:50:15.54Z",
            "zId": [
                "5d5d7ce0c89852e7bad4a4ef"
            ]
        }, // ...etc 

    ]

1 Ответ

0 голосов
/ 14 октября 2019

Спасибо за документы. К сожалению, я не знаю способа извлечь только те документы, которые имеют значение поля max timestamp.

Следующий запрос позволит вам выполнить фильтрацию по status и сгруппировать по eId, а затем получить максимальное значение timestamp, но он не будет возвращать документы, имеющие максимальное значение метки времени.

{
    "size": 0,
    "query": {
        "term": {
            "status": 1
        }
    },
    "aggregations": {
        "eId_group": {
            "terms": {
                "field": "eId"
            },
            "aggregations": {
                "max_timestamp": {
                    "max": {
                        "field": "timestamp"
                    }
                }
            }
        }
    }
}

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

{
    "size": 0,
    "query": {
        "term": {
            "status": 1
        }
    },
    "aggregations": {
        "eId_group": {
            "terms": {
                "field": "eId"
            },
            "aggregations": {
                "max_timestamp": {
                    "max": {
                        "field": "timestamp"
                    }
                },
                "top_documents": {
                    "top_hits": {
                        "size": 20,
                        "sort": { "timestamp": "desc"}
                    }
                }
            }
        }
    }
}

Я использовал следующее отображение для индекса

PUT /test_index
{
    "mappings": {
        "properties": {
            "timestamp": {
                "type": "date"
            },
            "eId": {
                "type": "keyword"
            },
            "zId": {
                "type": "keyword"
            },
            "status": {
                "type": "keyword"
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...