elasticsearch更新文档类型

时间:2014-11-20 05:35:49

标签: javascript elasticsearch

我有一个索引'推文'和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);
});

2 个答案:

答案 0 :(得分:2)

你无法改变文件的类型(至少我不知道)。

为什么不提取ID,您保留技术_id用于技术用途,并为您的文档提供一个很好的功能ID,以便在您的应用中使用!然后,您可以删除活动文档并创建非活动文档,并保留功能ID。

或者事件更好,在文档中添加一个活动/非活动标志,这样您就可以将文档标记为已删除,并创建一个很好的别名" active"过滤掉非活动文档。这样,您就可以以超级好的方式请求您的活动文档。

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

答案 1 :(得分:0)

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

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"
        }
      }
    }
  }
}'

现在,回到你的分割类型,你可以使用别名来完成同样的事情,但外观是他们已被移动/删除。别名可以动态添加或when the index is created

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别名以包含两者过滤索引和旧索引。