如何避免将重复文档插入ElasticSearch

时间:2017-03-27 06:33:00

标签: javascript node.js elasticsearch web-scraping ebay-api

我使用node.js / request抓取大量项目并将字段映射到ElasticSearch文档。原始文档的ID字段永远不会改变:

0       -> 49
25      -> 49
49      -> 49
50      -> 99
75      -> 99
99      -> 99
100     -> 149
2138    -> 2149
2150    -> 2199
48.5    -> 49
49.5    -> 99
50.5    -> 99

我想定期刷新"无论出于何种原因,看看哪些原始商品不再可用。目前,我有一个直接擦除的脚本,只需插入Elastic。

有没有办法在插入之前检查具有相同ID的项目是否已存在?我不想结束大量重复。

4 个答案:

答案 0 :(得分:1)

您是否将自己的ID用作文档_id?然后,使用operation type可以很容易地指定只应创建具有特定ID的文档,但不能覆盖该文档:

PUT your-index/your-type/123456/_create
{
    "foo" : "bar",
}

答案 1 :(得分:0)

当您使用批量api将数据推送到弹性时,您可以执行索引操作,并将_id用作源数据ID,在这种情况下,弹性将创建或替换文档(如果存在具有相同ID的文档),这里是示例批量操作

function createBulkBody(items, indexName) {
  var result = [];
  _.forEach(items, function(item) {
    result.push({
      index: {
        _index: indexName,
        _type: item.type,
        _id: item.ID
      }
    });
    result.push(item);
  });
  return result;
}

然后使用批量api推送数据,

   var body = createBulkBody(items, indexName);
   esClient.bulk({
     body: body
   }, function(err, resp) {
     if (err) {
       console.log(err);
     } else {
     console.log(resp);
     }
   });

希望这有帮助

答案 2 :(得分:0)

如果要在尝试插入项目之前检查项目是否存在,则可以只查询数据库中的此文档。如果结果不为空,则表示已存在具有此id的文档。

您可以使用term查询:

q = {'term': {'id': '123456'}}

我认为这将非常耗时,但这是一种确保不会插入重复内容的方法。

答案 3 :(得分:0)

假设您使用的是Elasticsearch Javascript API,则可以执行简单的get request on a known ID

client.get({
  index: 'myindex',
  type: 'mytype',
  id: 1
}, function (error, response) {
  // ...
});

404响应状态表示文档尚不存在:

Example get request