Node.js使用Elasticsearch按日期降序排序报错问题求助
问题根因
- ES客户端查询参数结构错误
你使用的Node.js Elasticsearch客户端版本要求搜索相关的排序、查询条件必须放在body字段下,你直接将sort放在参数顶层时,客户端序列化参数错误,将对象数组转为了[object Object]字符串传给ES服务端,导致服务端无法识别排序字段,抛出对应错误。 - 索引映射配置无效
你将mappings配置写在了写入单条文档的client.index方法参数中,该方法不支持设置索引映射,所以你期望的createdAt日期类型映射实际没有生效,字段类型由ES自动推断,也可能引发排序异常。
解决步骤
- 修正查询代码结构
如果使用的是7.x及以上版本的@elastic/elasticsearch客户端,调整查询参数如下:
let query={ index: 'tokens', from: 0, size: 100, body: { sort: [{"createdAt":{"order":"desc"}}] } } // 条件查询逻辑也对应放到body内,示例: // if(req.query.allTokens) { // query.body.query = { // wildcard: { product: `*${req.query.product}*` } // } // } client.search(query) .then(resp => { return res.status(200).json({ tokens: resp.hits.hits }) }).catch(err=>{ console.log(err); return res.status(500).json({ msg:'Error', err }); })
如果使用的是6.x及更早版本的客户端,也可以直接用字符串格式配置sort:
let query={ index: 'tokens', from: 0, size: 100, sort: 'createdAt:desc' }
- 修正索引映射配置
先删除已存在的测试索引(如果线上环境可通过reindex迁移数据,测试环境直接删除即可),再提前创建索引配置正确映射,这段代码只需要执行一次:
// 创建索引+配置映射 await client.indices.create({ index: 'tokens', body: { mappings: { properties: { createdAt: { type: "date", format: "strict_date_optional_time_nanos" } } } } })
后续写入文档时删除mappings参数即可:
await client.index({ index:"tokens", id: data.fingerprint, body:{ "policyID": data.policyid, "metadata": data.metadata, "assetID": data.assetID, "name": data.name, "quantity": data.quantity, "createdAt": data.time, "fingerprint": data.fingerprint } },function (err,resp,status) { console.log("response",resp); console.log("--------------------------------------------------------"); })
完成以上修改后即可正常按createdAt字段降序返回数据。
内容的提问来源于stack exchange,提问作者user16771164
相关产品推荐
相关产品推荐

