弹性搜索更新文档类型

elasicsearch updating document type

本文关键字:文档 类型 更新 搜索      更新时间:2023-09-26

我有一个索引"推文"和 2 种类型"活动"和"非活动"。当我创建一个文档时,我使用以下代码(对于node.js)在tweets''active中创建文档。

删除

推文时,我不想完全删除文档,但我想将文档(本身)"移动"为"非活动"类型,以便我可以保留文档及其_id等以供内部使用。

如何更改文档类型?有什么想法吗?

client.create({
    index: 'tweets',
    type: 'active',
    body: jsonData
}, function (error, response) {
    if (error)
        return callback("ERROR");
    if (response)
        return callback(response._id);
});

您无法更改文档的类型(至少我不知道)。

为什么不抽象 ID,你保留技术_id以供技术使用,并给你的文档一个很好的功能 ID 在你的应用程序中使用!然后,您可以删除活动文档并创建非活动文档,保留功能 ID。

或者更好的事件,在您的文档中添加一个活动/非活动标志,这样您只需将文档标记为已删除,然后制作一个漂亮的别名"活动"来过滤掉非活动文档。这样,您就可以以一种超级好的方式请求您的活动文档。

别名的文档 -> http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/indices-aliases.html

您无法真正移动文档。以一种奇怪的方式,你可以,但这不是真正的预期方法,它肯定有怪癖:

curl -XPOST localhost:9200/tweets/active/tweet-to-move/_update -d '{
  "doc" : {
    "_type" : "inactive"
  }
}'

上面的更新利用了这样一个事实,即您的类型实际上只是文档的顶级元数据字段(_type)。这样做是各种错误的,尤其是因为它修改了_source 。同一索引中的所有文档都一起存储在同一个分片上,这就是为什么这种工作(注意:它在 1.2.2 中以两种类型结束)。

虽然您绝对不想使用上述示例,但您应该执行类似操作。

与其创建两个单独的类型(因为它们位于同一个索引上并且无论如何都是相同的),不如只使用带有active(或者相反,inactive)字段的单个类型创建两个单独的索引(随着非活动推文数量的增加,随着时间的推移,这可能会产生更好的性能)。

curl -XPUT localhost:9200/tweets -d '{
  "mappings" : {
    "tweet" : {
      "properties" : {
        "user" : {
          "type" : "string",
          "index" : "not_analyzed"
        },
        "message" : {
          "type" : "string"
        },
        "inactive" : {
          "type" : "boolean"
        }
      }
    }
  }
}'

现在,回到拆分类型,您可以使用别名来完成相同的操作,但看起来它们已被移动/删除。别名可以动态添加,也可以在创建索引时添加:

curl -XPUT localhost:9200/tweets -d '{
  "mappings" : {
    "tweet" : {
      ...
    }
  },
  "aliases" : {
    "active" : {
      "filter" : {
        "bool" : { 
          "must_not" : {
            "term" : { "inactive" : true }
          }
        }
      }
    },
    "inactive" : {
      "filter" : {
        "term" : { "inactive" : true }
      }
    }
  }
}'

通过别名设置,您现在可以通过更新inactive字段来"移动"文档(实际上没有移动;文档保持在同一索引甚至同一分片上)。

创建映射后(这是过滤别名的必要步骤,这是 1.4 中的新功能),然后您可以根据需要开始插入默认活动文档:

curl -XPUT localhost:9200/tweets/tweet/12345 -d '{
  "user" : "kimchy"
  "message" : "Trying out Elasticsearch Aliases!"
}'

当您确定它们处于非活动状态时,只需更新它:

curl -XPOST localhost:9200/tweets/tweet/12345/_update -d '{
  "doc" : {
    "inactive" : true
  }
}'

要搜索活动文档,您只需使用别名:

# Assumes there is only one type defined (otherwise it searches all of them):
curl -XGET localhost:9200/active/_search -d '{
  "query" : { "match_all" : { } }
}'
# Searches only active tweets
curl -XGET localhost:9200/active/tweet/_search -d '{
  "query" : { "match_all" : { } }
}'

和非活动文档:

curl -XGET localhost:9200/inactive/_search -d '{
  "query" : { "match_all" : { } }
}'
curl -XGET localhost:9200/inactive/tweet/_search -d '{
  "query" : { "match_all" : { } }
}'

注意:如果您想同时搜索两者,请不要浪费时间使用别名,而是直接触摸索引:

curl -XGET localhost:9200/tweets/_search -d '{
  "query" : { "match_all" : { } }
}'

上所述,这种方法有两个缺点:

  1. 它要求使用筛选器来查找活动/非活动文档。这是在第一次使用时缓存的,因此速度非常快,但这可能是一个不必要的步骤,可以从 #2 的解决方案中受益。

    请注意,上面的两个别名使用相同的过滤器可能很有用,因此它只需要缓存一次(然后根据需要反转)。

  2. 所有文档都位于同一索引上,因此位于相同的分片上。随着时间的推移,您很可能会有很多无用的、不活跃的文档使分片混乱。如果这确实是一个问题,那么您可以开始删除旧的、非活动的文档,也可以使用两个索引(需要一个索引然后删除或"移动");使用两个索引意味着您可以删除筛选器。有趣的是,您可以通过将最近不活动的文档保留在同一索引中来组合这一点,并拥有另一个索引,该索引在很长一段时间后被移动到该索引,然后更新inactive别名以包含过滤后的索引和旧索引。