elasticsearch - 如何将文档移动到不同的 ID

标签 elasticsearch

我想将文档移动到新的 id,以便它在文档 API 中的另一个 url 上可用。有两种方法可以做到这一点:

1

  • 删除旧id的文档
  • 用新的id创建文档

2

  • 用新的id创建文档
  • 删除旧id的文档

方法 1 可能会导致文档不会在搜索中返回。方法 2 可能会导致文档在搜索中多次返回。

有什么办法可以解决吗?

最佳答案

当您创建(索引)或删除文档时,这只会在索引刷新后反射(reflect)在搜索中。所以在实践中你的两种方法都有相同的结果: 直到索引刷新

  • 旧文档将在搜索中返回,但使用文档 API (GET/indexname/type/id) 将不可用
  • 新文档将通过文档 API 提供,但不会出现在搜索中。

当您快速连续执行索引和删除操作时,甚至可能在单个批量请求中,操作的顺序并不重要。默认情况下,刷新间隔为一秒,因此差异将一直保持到该时间。您可以通过在索引上发出刷新命令来立即强制刷新:

curl -XPOST http://127.0.0.1:9200/testidx/_refresh

在下面的最后一节中提供了事件顺序的说明。

通过添加 URL 参数 refresh=true,也可以在批量请求后强制刷新。因此,如果您确实需要更改文档的 ID,我会按如下方式进行:

  1. 可选择禁用自动索引刷新
    1. 创建新文档
    2. 删除旧文档
    3. 刷新索引
  2. 重新启用自动索引刷新(如果在 1. 中禁用)

例子:

将文档从 ID 77 移动到 ID 99:

curl -XPOST localhost:9200/testidx/foo/_bulk?refresh=true --data-binary @bulk.json

文件 bulk.json 包含类似的内容

{"index": {"_id": "123"}}
{ ... old document source ... }
{"delete": {"_id": "99"}}

但是,您真的需要更改 ID,还是可以围绕该要求进行工程设计?也许不要以这种方式使用文档 API,而是在每个文档中包含例如 "path" 字段,并基于此(基于搜索 API)制作 URL 方案。然后,您可以通过使用新的 "path" 字段更新文档来移动(更改 URL 路径)文档。

搜索索引刷新示意图

首先添加 doc 77 并在搜索中看到它:

+ curl -XPUT 'http://127.0.0.1:9200/testidx/foo/77' -d '{"boo": "baa"}'
{
  "_index" : "testidx",
  "_type" : "foo",
  "_id" : "77",
  "_version" : 1,
  "created" : true
}

+ curl -XPOST http://127.0.0.1:9200/testidx/_refresh
{"_shards":{"total":10,"successful":5,"failed":0}}

+ curl -XGET 'http://127.0.0.1:9200/testidx/foo/_search'
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "testidx",
      "_type" : "foo",
      "_id" : "77",
      "_score" : 1.0,
      "_source":{"boo": "baa"}
    } ]
  }
}

+ curl -XPUT 'http://127.0.0.1:9200/testidx/_settings' -d '{"settings": { "index.refresh_interval": "-1"}}'
{
  "acknowledged" : true
}

然后添加一个新的doc 99:

+ curl -XPUT 'http://127.0.0.1:9200/testidx/foo/99' -d '{"boo": "baa"}'
{
  "_index" : "testidx",
  "_type" : "foo",
  "_id" : "99",
  "_version" : 1,
  "created" : true
}

99 还没有出现在搜索中:

+ curl -XGET 'http://127.0.0.1:9200/testidx/foo/_search'
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "testidx",
      "_type" : "foo",
      "_id" : "77",
      "_score" : 1.0,
      "_source":{"boo": "baa"}
    } ]
  }
}

...但是在文档 API 中:

+ curl -XGET 'http://127.0.0.1:9200/testidx/foo/99'
{
  "_index" : "testidx",
  "_type" : "foo",
  "_id" : "99",
  "_version" : 1,
  "found" : true,
  "_source":{"boo": "baa"}
}

删除77后,搜索仍然显示77(但不是99):

+ curl -XDELETE 'http://127.0.0.1:9200/testidx/foo/77'
{
  "found" : true,
  "_index" : "testidx",
  "_type" : "foo",
  "_id" : "77",
  "_version" : 2
}

+ curl -XGET 'http://127.0.0.1:9200/testidx/foo/_search'
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "testidx",
      "_type" : "foo",
      "_id" : "77",
      "_score" : 1.0,
      "_source":{"boo": "baa"}
    } ]
  }

但是文档API已经没有77了:

+ curl -XGET 'http://127.0.0.1:9200/testidx/foo/77'
{
  "_index" : "testidx",
  "_type" : "foo",
  "_id" : "77",
  "found" : false
}

但刷新后,搜索结果反射(reflect)的是当前内容:

+ curl -XPOST http://127.0.0.1:9200/testidx/_refresh
{"_shards":{"total":10,"successful":5,"failed":0}}

+ curl -XGET 'http://127.0.0.1:9200/testidx/foo/_search'
{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.0,
    "hits" : [ {
      "_index" : "testidx",
      "_type" : "foo",
      "_id" : "99",
      "_score" : 1.0,
      "_source":{"boo": "baa"}
    } ]
  }
}

关于elasticsearch - 如何将文档移动到不同的 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25483668/

相关文章:

python - Python扭曲的elasticsearch连接

elasticsearch - ElasticSearch-所有前几天的总和

elasticsearch - 无痛脚本更新无法实际更新文档

javascript - 使用 elasticsearch.js 时出现 CORS 错误

elasticsearch - 有什么办法可以在Elastic Search中匹配类似匹配

ubuntu - 无法从主机操作系统访问 Vagrant VM 中的 Elasticsearch 2.0

c# - 添加自定义分析器时,CompletionSuggester停止工作。 NEST C#

elasticsearch - 有没有一种方法可以在汇总后拉回字段名称?

python - 过滤器在Elasticsearch中不起作用

elasticsearch - 添加具有与映射中指定值不同类型的值的字段