gpt4 book ai didi

elasticsearch - 如何等到所有批量写入都在 Elasticsearch api 中完成

转载 作者:行者123 更新时间:2023-11-29 02:48:16 25 4
gpt4 key购买 nike

使用 NodeJS Elasticsearch 客户端。尝试编写数据导入程序以从 MongoDB 批量导入文档。我遇到的问题是索引刷新似乎没有等到所有文档都写入弹性文件后才检查计数。

使用node中的streams API读取记录成批,然后使用elastic API bulk命令写入记录。如下图所示:

function rebuildIndex(modelName, queryStream, openStream, done) {
logger.debug('Rebuilding %s index', modelName);
async.series([
function (next) {
deleteType(modelName, function (err, result) {
next(err, result);
});
},
function (next) {
var Model;
var i = 0;
var batchSize = settings.indexBatchSize;
var batch = [];
var stream;

if (queryStream && !openStream) {
stream = queryStream.stream();
} else if (queryStream && openStream) {
stream = queryStream;
}else
{
Model = mongoose.model(modelName);
stream = Model.find({}).stream();
}

stream.on("data", function (doc) {
logger.debug('indexing %s', doc.userType);
batch.push({
index: {
"_index": settings.index,
"_type": modelName.toLowerCase(),
"_id": doc._id.toString()
}
});
var obj;
if (doc.toObject){
obj = doc.toObject();
}else{
obj = doc;
}
obj = _.clone(obj);

delete obj._id;
batch.push(obj);
i++;
if (i % batchSize == 0) {
console.log(chalk.green('Loaded %s records'), i);
client().bulk({
body: batch
}, function (err, resp) {
if (err) {
next(err);
} else if (resp.errors) {
next(resp);
}
});
batch = [];
}
});

// When the stream ends write the remaining records
stream.on("end", function () {
if (batch.length > 0) {
console.log(chalk.green('Loaded %s records'), batch.length / 2);
client().bulk({
body: batch
}, function (err, resp) {
if (err) {
logger.error(err, 'Failed to rebuild index');
next(err);
} else if (resp.errors) {
logger.error(resp.errors, 'Failed to rebuild index');
next(resp);
} else {
logger.debug('Completed rebuild of %s index', modelName);
next();
}
});
} else {
next();
}

batch = [];
})
}

],
function (err) {
if (err)
logger.error(err);
done(err);
}
);
}

我使用这个助手来检查索引中的文档计数。没有超时,索引中的计数是错误的,但是有超时就没问题了。

/**
* A helper function to count the number of documents in the search index for a particular type.
* @param type The type, e.g. User, Customer etc.
* @param done A callback to report the count.
*/
function checkCount(type, done) {
async.series([
function(next){
setTimeout(next, 1500);
},
function (next) {
refreshIndex(next);
},
function (next) {
client().count({
"index": settings.index,
"type": type.toLowerCase(),
"ignore": [404]
}, function (error, count) {
if (error) {
next(error);
} else {
next(error, count.count);
}
});
}
], function (err, count) {
if (err)
logger.error({"err": err}, "Could not check index counts.");
done(err, count[2]);
});
}

并且这个助手应该在更新完成后刷新索引:

// required to get results to show up immediately in tests. Otherwise there's a 1 second delay
// between adding an entry and it showing up in a search.
function refreshIndex(done) {
client().indices.refresh({
"index": settings.index,
"ignore": [404]
}, function (error, response) {
if (error) {
done(error);
} else {
logger.debug("deleted index");
done();
}
});
}

加载器工作正常,除了由于批量加载和计数检查之间的时间导致此测试失败:

it('should be able to rebuild and reindex customer data', function (done) {
this.timeout(0); // otherwise the stream reports a timeout error
logger.debug("Testing the customer reindexing process");

// pass null to use the generic find all query
searchUtils.rebuildIndex("Customer", queryStream, false, function () {
searchUtils.checkCount("Customer", function (err, count) {
th.checkSystemErrors(err, count);
count.should.equal(volume.totalCustomers);
done();
})
});
});

我观察到测试计数中的随机结果。使用人为延迟(checkCount 函数中的setTimeout),然后计数匹配。所以我得出结论,文档最终写入了 elastic,测试将通过。我认为 indices.refresh 基本上会强制等待,直到文档全部写入索引,但它似乎不适用于这种方法。

当数量达到实际生产水平时,setTimeout hack 并不是真正可持续的....那么我如何才能确保在检查文档计数之前将批量调用完全写入弹性索引?

最佳答案

看看“刷新”参数 ( elasticsearch documentation )

例如:

let bulkUpdatesBody = [ bulk actions / docs to index go here ]
client.bulk({
refresh: "wait_for",
body: bulkUpdatesBody
});

关于elasticsearch - 如何等到所有批量写入都在 Elasticsearch api 中完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36660826/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com