elasticsearch,Javascript,Node.js,Mongodb,elasticsearch" /> elasticsearch,Javascript,Node.js,Mongodb,elasticsearch" />

Javascript Elasticsearch与MongoDB聚合-与示例的开发比较

Javascript Elasticsearch与MongoDB聚合-与示例的开发比较,javascript,node.js,mongodb,elasticsearch,Javascript,Node.js,Mongodb,elasticsearch,我正在NodeJS平台中将MongoDB查询转换为Elasticsearch。在开发过程中,我在Elasticsearch查询中对数据进行分组和筛选(获取嵌套对象,如hits.hits.\u source)时遇到了一些困难,就像我们在MongoDB查询中所做的那样 例如:- UserModel.aggregate([ { $match: { uId: req.body.uId, timestamp: { $gte: req.body.date, $

我正在NodeJS平台中将MongoDB查询转换为Elasticsearch。在开发过程中,我在Elasticsearch查询中对数据进行分组和筛选(获取嵌套对象,如hits.hits.\u source)时遇到了一些困难,就像我们在MongoDB查询中所做的那样

例如:-

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,并按eId分组
  • 根据该结果,按时间戳分组并获得最大时间戳值
  • 预期结果:-

    [
            {
                "_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 
    
        ]
    

    谢谢你的文件。遗憾的是,我不知道如何仅检索具有max timestamp字段值的文档

    下面的查询将允许您按
    status
    进行筛选,并按
    eId
    进行分组,然后获取最大时间戳值,但它不会返回具有最大时间戳值的文档

    {
        "size": 0,
        "query": {
            "term": {
                "status": 1
            }
        },
        "aggregations": {
            "eId_group": {
                "terms": {
                    "field": "eId"
                },
                "aggregations": {
                    "max_timestamp": {
                        "max": {
                            "field": "timestamp"
                        }
                    }
                }
            }
        }
    }
    
    第二个查询使用聚合来检索按
    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"
                }
            }
        }
    }
    

    谢谢你的文件。遗憾的是,我不知道如何仅检索具有max timestamp字段值的文档

    下面的查询将允许您按
    status
    进行筛选,并按
    eId
    进行分组,然后获取最大时间戳值,但它不会返回具有最大时间戳值的文档

    {
        "size": 0,
        "query": {
            "term": {
                "status": 1
            }
        },
        "aggregations": {
            "eId_group": {
                "terms": {
                    "field": "eId"
                },
                "aggregations": {
                    "max_timestamp": {
                        "max": {
                            "field": "timestamp"
                        }
                    }
                }
            }
        }
    }
    
    第二个查询使用聚合来检索按
    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"
                }
            }
        }
    }
    

    我对mongoDb了解不够,无法回答您的问题,但如果您能提供一套文档和预期结果,我可以尝试给您一个答案。@Pierre NicolasMougel谢谢。将添加文档。@Pierre NicolasMougel数据已添加。您能帮助我吗?我对mongoDb了解不够,无法回答您的问题,但如果您能提供一套文档和预期结果,我可以尝试给您一个答案。@Pierre NicolasMougel谢谢。将添加文档。@Pierre NicolasMougel数据已添加。你能帮我吗?这个查询将在正文中:{}对吗?而且,我也收到了错误,因为默认情况下,文本字段上禁用了[Ilawk_argument_exception]字段数据。在[employeeId]上设置fielddata=true,以便通过取消反转索引将fielddata加载到内存中。请注意,这可能会占用大量内存。或者使用关键字字段。注意:-添加了所有字段的关键字。但是仍然会出现一些错误。是的,您应该对要执行聚合的字段使用
    关键字
    类型。如果同时搜索此字段,则可以使用其他类型创建子字段。其他错误是什么?您的时间戳值也没有正确格式化为ISO 8601表示法。您应该删除:after T,或者您可以更改日期解析格式。我已经用我使用的映射更新了答案。这个查询将在主体内:{}对吗?而且,我也收到了错误,因为默认情况下,文本字段上禁用了[Ilawk_argument_exception]字段数据。在[employeeId]上设置fielddata=true,以便通过取消反转索引将fielddata加载到内存中。请注意,这可能会占用大量内存。或者使用关键字字段。注意:-添加了所有字段的关键字。但是仍然会出现一些错误。是的,您应该对要执行聚合的字段使用
    关键字
    类型。如果同时搜索此字段,则可以使用其他类型创建子字段。其他错误是什么?您的时间戳值也没有正确格式化为ISO 8601表示法。您应该删除:after T,或者您可以更改日期解析格式。我已经用我使用的映射更新了答案。