Node.js从Elasticsearch取文档title到数组遇空数组问题求助
解决Node.js读取Elasticsearch文档后titles数组为空的问题
这个需求完全可以用JavaScript实现,问题出在你对异步代码的执行顺序理解上,我来帮你分析并修正:
问题根源
esClient.search()是一个异步操作,它返回一个Promise对象,只有当Elasticsearch服务器返回结果后,.then()里的回调函数才会执行。但你现在的console.log(titles)是在调用search()之后立刻执行的——这时候异步请求还没完成,.then()里的titles.push()逻辑根本没机会运行,所以输出的自然是空数组。另外你的错误处理里还有个小问题:console.trace('err.message')应该改为console.trace(err.message),否则只会打印字符串而不是实际错误信息。
修正方案一:将输出逻辑移到异步回调内
把console.log(titles)放到.then()的回调里,确保等数据返回并填充数组后再输出:
let elasticsearch = require('elasticsearch') const esClient = new elasticsearch.Client({ host: '127.0.0.1:9200', log: 'error' }); let titles = new Array() esClient.search({ index: 'myindex', type: 'mytype', // 注意:Elasticsearch 7.x及以上版本已废弃type,若使用新版本请移除该参数 body: { size: 5, from: 0, query: { match_all: {} } } }).then(function (resp) { var hits = resp.hits.hits; hits.forEach((hit, index) => titles.push(hit._source.title)); console.log(titles); // 移到这里,确保数组已填充 }, function (err) { console.trace(err.message); // 修正:打印实际错误信息 });
修正方案二:使用async/await语法(更简洁易读)
现代Node.js支持async/await语法,可以让异步代码看起来像同步代码,逻辑更清晰,还能避免回调嵌套:
const elasticsearch = require('elasticsearch'); const esClient = new elasticsearch.Client({ host: '127.0.0.1:9200', log: 'error' }); // 用async函数包裹异步逻辑 async function getTitles() { try { const resp = await esClient.search({ index: 'myindex', type: 'mytype', // 新版本Elasticsearch请移除该参数 body: { size: 5, from: 0, query: { match_all: {} } } }); const hits = resp.hits.hits; const titles = hits.map(hit => hit._source.title); // 用map直接生成目标数组,更简洁 console.log(titles); return titles; // 如果需要在其他地方使用这个数组,可以返回它 } catch (err) { console.trace(err.message); } } // 调用函数 getTitles();
额外提示
如果你使用的是Elasticsearch 7.x及以上版本,type参数已经被官方废弃,建议直接移除该参数,否则可能会收到警告或报错。
内容的提问来源于stack exchange,提问作者M. Ben
相关产品推荐
相关产品推荐

