【Elasticsearch入门】ElasticSearch索引

索引是具有相同结构的文档集合。在 Elasticsearch中索引是个非常重要的内容,对Elasticsearch的大部分操作都是基于索引来完成的。

1、索引管理

1.1、创建索引

创建索引的时候可以通过修改 number_of_shards和 number_of_replicas参数的数量来修改分片和副本的数量。在默认的情况下分片的数量是5个(7.0版本默认是1个),副本的数量是1个。

后面可以通过 update- index-settings API完成对副本数量的修改。例如

1.2、删除索引

请求:DELETE http://127.0.0.1:9200/secisland/
上面的示例删除了名为 secisland的索引。删除索引需要指定索引名称,别名或者通配符。
删除索引可以使用逗号分隔符,或者使用_all或*号删除全部索引。
为了防止误删除,可以设置 elasticsearch.yml属性 action.destructive_requires_name为true,禁止使用通配符或_all删除索引,必须使用名称或别名才能删除该索引。

1.3、获取索引

获取索引接口允许从一个或多个索引中获取信息。
请求:GET http://127.0.0.1:9200/secisland/
通过这个请求会把系统中的信息都显示出来,包括默认的一些配置,例如上面的返回值为:

上面的示例获取名为 secisland的索引。获取索引需要指定索引名称,别名或者通配符。获取索引可以使用通配符获取多个索引,或者使用_all或*号获取全部索引。
返回结果过滤:可以自定义返回结果的属性。
请求:GET http://127.0.0.1:9200/secisland/_settings,_mappings
上面示例只返回 secisland索引的 settings和 mappings属性。可配置的属性包括_settings、_mappings、_warmers和_aliases。如果索引不存在,系统会返回一个错误内容,例如:

1.4、打开/关闭索引

打开/关闭索引接口允许关闭一个打开的索引或者打开一个已经关闭的索引。关闭的索引只能显示索引元数据信息,不能够进行读写操作。
打开/关闭索引的方式是/{索引名}/_close或者/{索引名}/_open,完整示例如下。
请求:POST 127.0.0.1:9200/secisland/_close,关闭索引。

请求:POST127.0.0.1:9200/secisland/_open,打开索引。

可以同时打开或关闭多个索引。如果指向不存在的索引会抛出错误。可以使用配置ignore_unavailable=true,不显示异常。
全部索引可以使用_all打开或关闭,或者使用通配符表示全部(比如*)。
设置config/elasticsearch.yml属性 action.destructive_requires_name为true,禁止使用通配符*或者_all标识索引。
因为关闭的索引会继续占用磁盘空间而不能使用,所以关闭索引接口可能造成磁盘空间的浪费。
禁止使用关闭索引功能,可以设置 settingscluster.indices.close.enable为 false,默认是true。

2、索引映射管理

在前面例子中 Elasticsearch创建文档的时候,是没有指定索引参数,这个时候系统会自动判断每个维度的类型,有很多时候需要我们进行一些更高级的设置,比如索引分词,是否存储等。

2.1、增加映射

API允许你向索引(index)添加文档类型(type),或者向文档类型(type)中添加字段(field)。

请求 http://127.0.0.1:9200/secisland/
{
  "mappings": {
    "properties": {
      "message": {
        "type": "text"
      }
    }
  }
}

以上接口添加索引名为 secisland,文档类型为默认为secisland,其中包含字段 message,字段类型是字符串:

2.1.1、多个索引设置映射

可以一次向多个索引添加文档类型。

请求:PUT http://127.0.0.1:9200/{index}/_mapping/{type}
{body}

{index}可以有多种方式,逗号分隔:比如test1,test2,test3,_all表示所有索引。通配符*表示所有。test*表示以test开头。
{type}需要添加或更新的文档类型。
{body}需要添加的字段或字段类型。

2.1.2、更新字段映射

在一般情况下,对现有字段的映射不会更新。对这个规则有一些例外。例如:

  • 新的属性被添加到对象数据类型的字段。
  • 新的多域字段被添加到现有的字段。
  • doc_values可以被棼用。
  • 增加了 ignore_above参数。

例如:

创建索引:

请求PUT http://127.0.0.1:9200/secisland/
{
  "mappings": {
    "properties": {
      "name": {
        "properties": {
          "first": {
            "type": "keyword"
          }
        }
      },
      "user_id": {
        "type": "keyword",
        "index": "false"
      }
    }
  }
}

修改索引:

http://127.0.0.1:9200/secisland/_mapping/
{
  "properties": {
    "name": {
      "properties": {
        "last": {
          "type": "keyword"
        }
      }
    },
    "user_id": {
      "type": "keyword",
      "index": "false",
      "ignore_above": 100
    }
  }
}

2.2、获取映射

GET http://127.0.0.1:9200/secisland/_mapping/             指定索引
GET http://127.0.0.1:9200/_all/_mapping/                  所有索引
GET http://127.0.0.1:9200/_mapping/                       与上一个一样
GET http://127.0.0.1:9200/secisland,secisland2/_mapping/  多个索引

3、索引别名

在 Elasticsearch所有的API中,对应的是一个或者多个索引。 Elasticsearch可以对个或者多个索引指定别名,通过别名可以查询到一个或者多个索引的内容。在内部,Elasticsearch会自动把别名映射到相应的索引上。可以对别名编写过滤器或者路由,在系统中别名不能重复,也不能和索引名重复。其实 Elasticsearch的别名机制有点像数据库中的视图。

添加别名:

PUT http://10.8.122.208:9200/_alias/
{
  "action": [
    {
      "add": {
        "index": "secisland",
        "alias": "alias1"
      }
    }
  ]
}

删除别名:

PUT http://10.8.122.208:9200/_alias/
{
  "action": [
    {
      "remove": {
        "index": "secisland",
        "alias": "alias1"
      }
    }
  ]
}

注意:别名没有修改的语法,当需要修改别名的时候,可以先删除别名,然后再增加别名,例如:

PUT http://10.8.122.208:9200/_alias/
{
  "action": [
    {"remove": {"index": "secisland","alias": "alias1"}},
    {"add": {"index": "secisland","alias": "alias2"}}
  ]
}

4、索引配置

在 Elasticsearch中索引有很多的配置参数,有些配置是可以在建好索引后重新进行设置和管理的,比如索引的副本数量、索引的分词等。

4.1、更新索引配置

在REST风格的URL设置中设置/_settings(所有索引)或者{index}/_settings,可以设置一个或者多个索引,例如

更新分词器。创建索引后可以添加新的分析器。添加分析器之前必须先关闭索引,添加之后再打开索引。

如上示例,先关闭 secisland索引,然后添加自定义分析器,分析器策略是空格分析器( whitespace),就是按照空格进行分词。

4.2、获取配置

索引中包含很多配置参数,可以通过下面命令获取索引的参数配置

GET http://127.0.0.1:9200/secisland/_settings

获取索引配置参数的请求格式如下:
host:port/{index)/_settings
{index}为索引名称,可以接收多种参数格式,* | _all | name1,name2
过滤配置参数的返回结果:
GET http://127.0.0.1:9200/secisland/_settings/name=index.number_*
name=index.number*设置将只返回 number_of_replicas, number_of_shards两个参数详情。

4.3、索引分析

索引分析(analysis)是这样一个过程:首先,把一个文本块分析成一个个单独的词(term),为了后面的倒排索引做准备。然后标准化这些词为标准形式,提高它们的“可搜索性”。这些工作是分析器(analyzers)完成的。一个分析器(analyzers)是一个组合,用于将三个功能放到一起:

  • 字符过滤器:字符串经过字符过滤器(character filter)处理,它们的工作是在标记化之前处理字符串。字符过滤器能够去除HTML标记,或者转换“&”为“and”。
  • 分词器:分词器(tokenizer)被标记化成独立的词。一个简单的分词器( tokenizer)可以根据空格或逗号将单词分开。
  • 标记过滤器:每个词都通过所有标记过滤(token filters)处理,它可以修改词(例如将"Quick"转为小写),去掉词(例如连接词像 “a”、“and”、“the”等),或者增加词(例如同义词像“jump”和“leap”)。

Elasticsearch提供很多内置的字符过滤器,分词器和标记过滤器。这些可以组合起来创建自定义的分析器以应对不同的需求。
测试分析器:

该结果将返回“ this is a test”使用 standard分析器后词的解析情况。
在该分析器下,将会分析成this,is,a,test四个词。
自定义分析器:

使用 keyword分词器、 lowercase分词过滤、字符过滤器是 html_strip,这3部分构成一个分词器。
上面示例返回分词结果是 this is a test,其中 html strip过滤掉了html字符。
也可以指定索引进行分词。URL格式如下:
http://127.0.0.1:9200/secisland_analyze
索引详情如下:如果想获取分析器分析的更多细节,设置 explain属性为true(默认是false),将输出分词器的分词详情。请求格式如下

4.4、索引模板

4.4.1、创建索引模板

索引模板就是创建好一个索引参数设置(settings)和映射(mapping)的模板,在创建新索引的时候指定模板名称就可以使用模板定义好的参数设置和映射。例子如下:

定义好模板可使用te*来适配,分片数量为1,默认文档类型 type1, _source的 enabled为 false。
也可以在模板中定义别名等其他属性。

4.4.2、删除索引模板

DELETE http://127.0.0.1:9200/_template/template_1
template_1为之前创建的索引模板名称。

4.4.3、获取索引模板

GET http://127.0.0.1:9200/_template/template_1
使用通配符或逗号分隔符
GET http://127.0.0.1:9200/_template/temp*
GET http://127.0.0.1:9200/_template/templatel,template2
获取所有索引模板:
GET http://127.0.0.1:9200/_template

4.4.4、多个模板匹配

有这样一种情况: template1、 template2两个模板,使用te*会匹配2个模板,最后合并两个模板的配置。如果配置重复,这时应该设置 order属性, order是从0开始的数字,先匹配 order数字小的,再匹配数字大的,如果有相同的属性配置,后匹配的会覆盖之前的配置。

4.5、重建索引

重建索引的最基本的功能是拷贝文件从一个索引到另一个索引,例如:

参数说明:
took:从开始到结束的整个操作的毫秒数。
updated:已成功更新的文档数。
created:成功创建的文档数。
batches:从重建索引拉回的滚动响应的数量
version_conflicts:重建索引中版本冲突数的数量。
failures:所有索引失败的数组。如果这是非空的,则请求将被中止。

由于 reindex是获取源索引的快照,而且目标索引是不同的索引,所以基本上不太可能产生冲突。在接口参数中可以增加dest来进行乐观并发控制。如果 version_type设置为internal会导致 Elasticsearch盲目转储文件到目标索引,任何具有相同类型和ID的文档将被重写。例如:

如果设置 version_type为 external将会导致 Elasticsearch保护源索引的版本,如果在目标索引中有一个比源索引旧的版本,则会更新文档。对于源文件中丢失的文档在目标中也会被创建。

设置 op_type为 create将导致 reindex在目标索引中仅创建丢失的文件。所有现有的文件将导致版本冲突。

正常情况下当发生冲突的时候 reindex过程将被终止,可以在请求体中设置"conflicts":"proceed'",可以只进行计算:

可以通过向源添加一个类型或者增加一个査询来限制文档的数量,比如只复制用户名为kimchy的文档:

在请求接口中可以列出源索引和类型,可以在一个接口中复制多个源。例如下面的例子将在 secisland和blog索引中的 semilog和post类型中拷贝数据,这包括 secisland索引中的“semilog”和“post”类型,也包括blog索引中的“semilog”和“post”类型。如果需要更具体的文档可以使用查询。当id产生冲突的时候是没有办法处理的,因为执行的顺序是随机的,所以目标索引将无法确定应该保存哪些文档:

也可以通过设置大小来限制处理文档的数量。这只会复制一个文件到 new_secisland索引中:

如果你想要复制特定的文档,可以使用排序。排序会降低效率,但在某些情况下,它是有意义的。如果可能的话,可以选择性地查询来确定复制的大小和排序。下面将从 secisland索引中复制10000文档到 new_secisland中:

_reindex同时支持使用脚本来修改文档。例如:

可以修改的元字段包括_id、_type、_index、_version、_routing、_parent、_timestamp、_ttl所以用脚本复制能力非常强大。
默认情况下,如果_reindex可以设置文档路由来进行路由保存,除非是通过脚本进行了改变。你可以设置dest参数来进行路由设置

  • keep:设置在匹配的每一个路由上发送请求的路由。这个是默认设置。
  • discard:为每一个匹配发送的请求设置为空。
  • =<some text>:设置为每一个匹配的文本请求发送路由上的路由。例如,你可以使用以下要求复制所有文件从源索引为“ company”等于“cat”的查询中复制到目标索引,目标索引的路由设置为cat:

默认情况下 _reindex每次处理的大小为100。可以在源参数中用size参数来进行修改:

URL参数: _reindex接口除了接收标准的参数例如 pretty,还支持 refresh, wait_for_completion、 consistency、 timeout参数。
在URL参数中发送 refresh会导致所有写入请求的索引被刷新。与索引接口中的 refresh参数不同,只有接收到新数据的分片会进行刷新。
如果请求包含 wait_for_completion= false, Elasticsearch将进行执行前检查后启动请求,然后返回一个task可用于任务API取消或得到任务的状态,现在一旦请求完成任务就不见了,找任务的最终结果的唯一地方是在 Elasticsearch日志文件中,这个问题将会在未来的版
本中修复。
consistency控制每次写请求必须多少份分片被响应。
timeout控制每个写请求等待可用的分片的时间。
任务查看:

_reindex可以用来建立索引的时候同时也可以修改列的名称,例如,源索引类型为:

可以通过_reindex来修改列的名称,例如:

可以通过_reindex来修改列的名称,例如:

5、索引监控

在 Elasticsearch中,系统提供了接口来监控索引的状态,包括索引的统计信息、碎片信息、恢复的状态和分片的信息,利用这些接口可以随时监控系统索引的状态。

5.1、索引统计

索引统计接口提供索引中不同内容的统计数据(其中的大多数统计数据也可以从节点级别范围取得)。
获取所有聚合以及索引的统计数据:
请求:GET http://127.0.0.1:9200/_stats
获取指定索引的统计数据:
请求:GET http://127.0.0.1:9200/index1,index2/_stats
默认情况返回所有统计数据,也可以在URL中指定需要返回的特定统计数据。指定数据如下表所示。

一些统计数据可以作用在字段粒度上,接受逗号分隔的字段列表。默认包含所有字段,如下所示:
fields——包含在统计数据中的字段列表。用作默认列表,除非提供了更明确的列表。
completion_fields——包含在完成建议统计数据中的字段列表。
fielddata_fields——包含在字段数据统计数据中的字段列表。

举一些例子:
获取所有索引的混合和刷新统计数据
GET http://127.0.0.1:9200/_stats/merge,refresh
获取分组 groupl和goup2的搜索统计数据
GET http://127.0.0.1:9200/_stats/search?groups=group1,group2

返回的统计数据在索引级别发生聚合,生成名为 primates和 total的聚合。其中, primates仅包含主分片的值,totl是主分片和从分片的累计值。
为了获取分片级别统计数据,需要设置 level参数为 shards。
注意,当分片在集群中移动的时候,它们的统计数据会被清除,视作它们在其他节点中被创建。另一方面,即使分片“离开”了一个节点,那个节点仍然会保存分片之前的统计数据。

5.2、索引分片

提供 Lucene索引所在的分片信息。可以用来提供分片和索引的更多统计信息,可能是优化信息,删除的“垃圾”数据,等等。
参数包括特定的索引,多个索引或者所有索引的分片请求如下:

其中参数见下表:

5.3、索引恢复

索引恢复接口提供正在进行恢复的索引分片信息。可以报告指定索引或者集群范围的恢复状态。
例如,获取 secisland1和 secisland2两个索引的恢复信息
GET http://127.0.0.1:9200/secisland1,secisland2/_recovery
去掉索引名可以査看集群范围的恢复状态:
GET http://127.0.0.1:9200/_recovery?pretty&human
选项列表:

  • detailed-—显示详细的视图。主要用来查看物理索引文件的恢复。默认为 false
  • active_only——显示那些现在正在进行的恢复。默认为 false

输出字段描述如表2-3所示。

5.4、索引分片存储

提供索引分片副本的存储信息。存储信息报告分片副本存在的节点、分片副本版本、指示分片副本最近的状态以及在开启分片索引时遭遇的任何异常。
默认情况下,只列出至少有一项未分配副本的分片的存储信息。
端点包括特定的索引、多个索引或者所有索引的分片:
GET http://127.0.0.1:9200/secisland/_shard_stores
GET http://127.0.0.1:9200/secisland1,secisland2/_shard_stores
GET http://127.0.0.1:9200/_shard_stores
列出存储信息的分片范围可以通过 status参数进行修改。默认是 yellow和red。使用green参数来列出所有指定副本分片的存储信息GET http://127.0.0.1:9200/_shard_stores?status=green

6、状态管理

在 Elasticsearch中还有一些和索引相关的重要接口需要介绍,这些接口包括清除索引缓存、索引刷新、冲洗索引、合并索引接口等,下面分别介绍。

6.1、清除缓存

清除缓存接口可以清除所有缓存或者关联一个或更多索引的特定缓存:
POST http://127.0.0.1:9200/secisland/_cache/clear
接口默认清理所有缓存,可以明确设置 query、 fielddata和 request来清理特定缓存。
所有关联特定字段的缓存也可以被清理,通过逗号分隔的相关字段列表来指定 fields参数。

6.2、索引刷新

刷新接口可以明确地刷新一个或多个索引,使之前最后一次刷新之后的所有操作被执行。(接近)实时能力取决于使用的搜索引擎。例如,内部的一个请求刷新被调用,但是默认刷新是一个周期性的安排。
POST http://127.0.0.1:9200/secisland/_refresh
刷新接口可以通过一条请求应用到多个索引,或者所有索引:
POST http://127.0.0.1:9200/secisland,elasticsearch/_refresh
POST http://127.0.0.1:9200/_refresh

6.3、冲洗

冲洗(flush)接口可以通过接口冲洗一个或多个索引。索引主要通过执行冲洗将数据保存到索引存储并且清除内部事务日志,以此来释放索引的内存空间。默认的, Elasticsearch使用内存启发式算法来自动触发冲洗操作的请求来清理内存:
POST http://127.0.0.1:9200/secisland/_flush

6.4、合并索引

合并接口可以强制合并一个或更多索引。合并分片数量和每个分片保存的 Lucene索引。强制合并可以通过合并来减少分片数量。
调用会被阻塞直到合并完成。如果htp连接丢失,请求会在后台继续执行,任何新的请求都会被阻塞直到前一个强制合并完成。
POST http://127.0.0.1:9200/secisland/_forcemerge

合并接口接受请求参数如下所示:

  • max_num_segments:用于合并的分片数量。为了充分合并索引,设置它的值为1。默认简单地检查是否需要执行合并,如果是,执行合并。
  • only_expunge_deletes:合并过程是否只删除分片中被删除的文档。在 Lucene中,文档不会从分片中删除,只是标记为删除。通过执行分片合并,一个不包含这些被删除的文档的新分片会被创建。这个标识可以只合并拥有删除文档的分片。默认值为 false。注意 index. merge policy. expunge_deletes_ allowed阈值不会被覆盖。
  • fush:强制合并之后是否执行冲洗。默认为true。

合并接口可以通过单次应用到多个索引,或者所有索引:
POST http://127.0.0.1:9200/secisland,elasticsearch/_forcemerge
POST http://127.0.0.1:9200/_forcemerge

7、文档管理

文档是具体的数据,一个文档有点像数据库中的一条记录,文档必须包含在一个索引中。

7.1、增加文档

新增文档是把一条新的文档增加到索引中,使之能够进行搜索,文档的格式是JSON格式。注意,在 Elasticsearch中如果有相同ID的文档存在,则更新此文档。例如我们在索引secilog中增加一条文档:

请求 PUT http://127.0.0.1:9200/secisland/_doc/1/
{
  "collect_type": "syslog",
  "collect_date": "2016-01-11T09:32:12",
  "message": "Failed password for root from 192.168. 21. 1 port 50790 ssh2"
}

返回值:

 

  • 返回值中的 shards提供了索引创建的过程信息,参数如下所示:
  • total——文档被创建的时候,在多少个分片中进行了操作,包括主分片和副本分片。
  • successful——成功建立索引分片的数量,当创建成功后,成功创建索引分片的数量最少是1。
  • failed失败建立索引分片的数量。

7.1.1、自动创建索引

当创建文档的时候,如果索引不存在,则会自动创建该索引。自动创建的索引会自动映射每个字段的类型。自动创建字段类型是非常灵活的,新的字段类型将会自动匹配字段对象的类型。比如字符串类型,日期类型。可以通过配置文件设置 actior.auto_create_index为false在所有节点的配置文件中禁用自动创建索引。自动映射的字段类型可以通过配置文件设置 index.mapper.dynamic为 false禁用。自动创建索引可以通过模板设置索引名称,例如:可以设置 action.auto_create_index为+aaa*,-bbb*,+ccc*,-*(+表示准许,-表示禁止)。

7.1.2、序列号

每个文档都有一个序列号,序列号的具体值放在创建索引的返回值中("_seq_no":)。通过序列号参数可以达到并发控制的效果。当在操作文档的过程中指定序列号,如果和序列号不一致的时候操作会被拒绝。序列号常用在对事务的处理中。

先查询一下文档:

GET http://127.0.0.1:9200/secisland/_doc/1/

返回值:

 

更新刚才查询的文档:

PUT http://127.0.0.1:9200/secisland/_doc/1?if_seq_no=11
{
  "collect_type": "syslog",
  "collect_date": "2019-01-11T09:32:12",
  "message": "Failed password for root from 192.168. 21. 1 port 50790 ssh2"
}

返回值:

 

从返回信息看到除了要设置if_seq_no外还需要一个加一个if_primary_term参数。

PUT http://127.0.0.1:9200/secisland/_doc/1?if_seq_no=11&if_primary_term=1
{
  "collect_type": "syslog",
  "collect_date": "2019-01-11T09:32:12",
  "message": "Failed password for root from 192.168. 21. 1 port 50790 ssh2"
}

返回值:

 

7.1.3、操作类型

系统同时支持通过 op_type=create参数强制命令执行创建操作,只有系统中不存在此文档的时候才会创建成功。如果不指定此操作类型,如果存在此文档,则会更新此文档。例如再次创建文档:

PUT http://127.0.0.1:9200/secisland/_doc/3?op_type=create
{
  "collect_type": "syslog",
  "collect_date": "2019-01-11T09:32:12",
  "message": "Failed password for root from 192.168. 21. 1 port 50790 ssh2"
}

返回值:

 

当不指定 op_type= create时候,则更新此文档。
创建操作的另一个写法为:http://127.0.0.1:9200/secisland/_doc/1/_create

7.1.4、自动创建ID

当创建文档的时候,如果不指定ID,系统会自动创建ID。自动生成的ID是一个不会重复的随机数。例如:

7.1.5、分片选择

默认情况下,分片的选择是通过ID的散列值进行控制。这个只可以通过 router参数进行手动的控制。可以在每个操作的基础上直接通过哈希函数的值来指定分片的选择。例如:
请求 POST http://127.0.0.1:9200/secisland/_doc?routing=secisland&pretty
在上面的例子中,分片的选择是通过指定 routing=secisland参数的哈希值来确定的。

7.1.6、其他说明

  • 分布式:索引操作主要是针对主节点的分片进行,当主节点完成索引操作后,如果有副本节点,则分发到副本中。
  • 一致性:为了防止当网络出现问题时写入不一致,系统只有在有效节点的数量大于定数量的时候生效(总结点数12+1),该值可以通过 action.write_consistency参数进行修改。
  • 刷新:更新的时候可以指定 refresh参数为true来立即刷新所有的副本,当 refresh设置为true的时候,系统做了充分的优化,不会对系统产生任何影响,需要注意的是查询操作 refresh参数没有任何的意义。
  • 空操作:当文档内容没有任何改变的时候,更新文档操作也会生效,具体体现在版本号会发生变化。如果不希望此情况发生,在更新的时候指定 detect_noop为true这个参数在创建索引的时候无效。
  • 超时:默认情况下系统的超时时间是1分钟。可以通过设置 timeout来修改超时的时间,例如 timeout=5m,表示超时的时间是5分钟。

7.2、更新删除文档

Elasticsearch的更新文档API准许通过脚本操作来更新文档。更新操作从索引中获取文档,执行脚本,然后获得返回结果。它使用版本号来控制文档获取或者重建索引。
在 Elasticsearch I中的更新操作是完全重新索引文件。
我们新建一个文档。

PUT test/_doc/1
{
    "counter" : 1,
    "tags" : ["red"]
}

7.2.1、脚本开启功能

在最新版本的 Elasticsearch中,基于安全考虑(如果用不到,请保持禁用),默认禁用了动态脚本功能。如果被禁用,在使用脚本的时候则报以下的错误:scripts of type [inline], operation [update] and lang [groovy] are disabled
可以用以下方式完全开启动态脚本功能,在 config/elasticsearch.yml文件最后添加以下代码:
script.inline:on
script.indexed:on
script.file:on
配置后,重启 Elasticsearch。

7.2.2、用脚本更新文稿

下面我们用脚本来更新此文档。

POST test/_update/1
{
    "script" : {
        "source": "ctx._source.counter += params.count",
        "lang": "painless",
        "params" : {
            "count" : 4
        }
    }
}

在脚本中除了 _source外其他内置参数也可以使用,例如 _index、_type、_id、_version、_routing、_parent、_timestamp、_ttl。
下面我们通过脚本增加一列。

POST test/_update/1
{
    "script" : "ctx._source.new_field = 'value_of_new_field'"
}

从中可以看出,文档中又增加了一列。
如果删除一列,请求和刚才的一样,参数变为:

POST test/_update/1
{
    "script" : "ctx._source.remove('new_field')"
}

甚至可以通过表达式来判断做某些事情。例如:下面的示例将删除tag字段包含blue的文件。

POST test/_update/1
{
    "script" : {
        "source": "if (ctx._source.tags.contains(params.tag)) { ctx.op = 'delete' } else { ctx.op = 'none' }",
        "lang": "painless",
        "params" : {
            "tag" : "green"
        }
    }
}

部分文档更新:该更新接口还支持更新部分文档,将文档合并到现有文档中(简单的递归合并、对象的内部合并、替换核心的“键/值”和数组)。例如:

POST test/_update/1
{
    "doc" : {
        "name" : "new_name"
    }
}

当文档指定的值与现有的 source合并,当新的文档和老的文档不一致的时候,文档将会被重新建立索引。当新旧文档一样的时候,则不进行重建索引的操作。可以通过设置detect_noop为 false,让任何情况下都重新建立索引,例如下面的更新操作:

POST test/_update/1
{
    "doc" : {
        "name" : "new_name"
    },
    "detect_noop": false
}

删除文档比较简单。

7.3、查询文档

Elasticsearch查询文档API准许用户通过文档的ID来查询具体的某一个文档。

请求 GET twitter/_doc/0

返回值:

{
    "_index" : "twitter",
    "_type" : "_doc",
    "_id" : "0",
    "_version" : 1,
    "_seq_no" : 10,
    "_primary_term" : 1,
    "found": true,
    "_source" : {
        "user" : "kimchy",
        "date" : "2009-11-15T14:12:12",
        "likes": 0,
        "message" : "trying out Elasticsearch"
    }
}

从返回的内容中可以有很多有用的信息,当然也包括原始的文档信息,放在 source字段中。
默认情况下,査询获得的数据接口是实时的,并且不受索引的刷新率影响,为了禁用实时性,可以将参数 realtime设置为 false,或全局设置 action.get.realtime为 false。

默认情况下,査询操作会返回 source字段,当然_source可以被禁用。例如

GET twitter/_doc/0?_source=false

当然如果你想获取_source中的一部分内容,可以用_source_include或者_source_exclude来包含或者过滤其中的某些字段,例如:

GET twitter/_doc/0?_source_includes=*.id&_source_excludes=entities

当一个文档内容非常多的时候,用包含或者过滤可以减少很多的网络负担。如果有多个,可以用逗号分开,或者用*通配符。

如果您只想指定包含,则可以使用较短的表示法:

GET twitter/_doc/0?_source=*.id,retweeted

get操作允许指定一组存储的字段,这些字段将通过传递stored_fields参数返回。 如果未存储请求的字段,则将忽略它们。 例如,考虑以下映射:

PUT twitter
{
   "mappings": {
       "properties": {
          "counter": {
             "type": "integer",
             "store": false
          },
          "tags": {
             "type": "keyword",
             "store": true
          }
       }
   }
}

然后添加一个文档:

PUT twitter/_doc/1
{
    "counter" : 1,
    "tags" : ["red"]
}

然后已这种方式访问:

GET twitter/_doc/1?stored_fields=tags,counter

返回结果:

{
   "_index": "twitter",
   "_type": "_doc",
   "_id": "1",
   "_version": 1,
   "_seq_no" : 22,
   "_primary_term" : 1,
   "found": true,
   "fields": {
      "tags": [
         "red"
      ]
   }
}

从文档本身获取的字段值始终作为数组返回。 由于未存储计数器字段,因此在尝试获取stored_field时,get请求会忽略它。

7.3.1、只获取文档内容

GET twitter/_source/1

您还可以使用相同的源过滤参数来控制将返回_source的哪些部分:

GET twitter/_source/1/?_source_includes=*.id&_source_excludes=entities

注意,_source端点还有一个HEAD变体,可以有效地测试document _source的存在。 如果在映射中禁用了现有文档,则该文档将没有_source。

HEAD twitter/_source/1

7.3.2、分片选择(routing)

可以在查询的时候指定路由选择(routing),当路由不存在的时候,返回为空值,此实例是事先做了路由的操作,例如:

GET twitter/_doc/2?routing=user1

7.3.3、查询参数

通过参数控制,查询的时候可以指定查询是在主节点上查询还是在副本节点上查询。参数有

  • primary:在主节点进行查询。
  • local:尽可能在本地节点上进行查询。
  • refresh:可以设置为true,使之在搜索操作前刷新相关的分片保证可以及时査询到。

但这个参数会消耗系统的资源,除非有必要,正常情况下不需要设置。例如:

GET http:/127.0.0.1:9200/secisland/_doc/1?_primary&_refresh=true

7.4、多文档操作

在 Elasticsearch对文档的操作中,之前介绍的都是对单个文档进行操作,其实Elasticsearch可以对多个文档同时操作。下面介绍多文档查询(bulk)。

7.4.1、多文档查询

多文档査询可以在同一个接口中查询多个文档,可以分别指定 index、type、id来进行多个文档的查询。响应包括所有查询到的文档数组,每个元素在结构上类似于单个文档查询。下面举例说明。

GET /_mget
{
    "docs" : [
        {
            "_index" : "test",
            "_type" : "_doc",
            "_id" : "1"
        },
        {
            "_index" : "test",
            "_type" : "_doc",
            "_id" : "2"
        }
    ]
}

返回值:

从中可以看出,一次查询了两个文档。
在査询的时候, index、type可以在URL中直接填写。例如下面两个请求和之前的是等价的。

GET /test/_mget
{
    "docs" : [
        {
            "_type" : "_doc",
            "_id" : "1"
        },
        {
            "_type" : "_doc",
            "_id" : "2"
        }
    ]
}
GET /test/_doc/_mget
{
    "docs" : [
        {
            "_id" : "1"
        },
        {
            "_id" : "2"
        }
    ]
}

对于上一种,可以用更加简化的方式查询:

GET /test/_doc/_mget
{
    "ids" : ["1", "2"]
}

7.4.2、字段过滤

默认情况下,将为每个文档(如果存储)返回_source字段。 与get API类似,您只能使用_source参数检索_source的部分(或根本不检索)。 您还可以使用url参数_source,_source_includes和_source_excludes来指定默认值,这些默认值将在没有按文档说明时使用。

GET /_mget
{
    "docs" : [
        {
            "_index" : "test",
            "_type" : "_doc",
            "_id" : "1",
            "_source" : false
        },
        {
            "_index" : "test",
            "_type" : "_doc",
            "_id" : "2",
            "_source" : ["field3", "field4"]
        },
        {
            "_index" : "test",
            "_type" : "_doc",
            "_id" : "3",
            "_source" : {
                "include": ["user"],
                "exclude": ["user.location"]
            }
        }
    ]
}

7.4.3、stored_fields

可以指定要为每个文档检索特定存储的字段以获取,类似于Get API的stored_fields参数。 例如:

GET /_mget
{
    "docs" : [
        {
            "_index" : "test",
            "_type" : "_doc",
            "_id" : "1",
            "stored_fields" : ["field1", "field2"]
        },
        {
            "_index" : "test",
            "_type" : "_doc",
            "_id" : "2",
            "stored_fields" : ["field3", "field4"]
        }
    ]
}

或者,您可以将查询字符串中的stored_fields参数指定为默认值,以应用于所有文档。

GET /test/_doc/_mget?stored_fields=field1,field2
{
    "docs" : [
        {
            "_id" : "1" 
        },
        {
            "_id" : "2",
            "stored_fields" : ["field3", "field4"] 
        }
    ]
}

7.4.4、路由

您还可以将路由值指定为参数:

GET /_mget?routing=key1
{
    "docs" : [
        {
            "_index" : "test",
            "_type" : "_doc",
            "_id" : "1",
            "routing" : "key2"
        },
        {
            "_index" : "test",
            "_type" : "_doc",
            "_id" : "2"
        }
    ]
}

在此示例中,将从对应于路由密钥key1的分片中提取文档test/_doc/2,但是将从对应于路由密钥key2的分片中提取文档test/_doc/1。

7.4.5、块操作

块操作可以在一个接口中处理文档的内容,包括创建文档、删除文档和修改文档。用块操作方式操作多个文档可以提高系统的效率。例如:

POST _bulk
{ "index" : { "_index" : "test", "_id" : "1" } }
{ "field1" : "value1" }
{ "delete" : { "_index" : "test", "_id" : "2" } }
{ "create" : { "_index" : "test", "_id" : "3" } }
{ "field1" : "value3" }
{ "update" : {"_id" : "1", "_index" : "test"} }
{ "doc" : {"field2" : "value2"} }

返回值:

{
   "took": 30,
   "errors": false,
   "items": [
      {
         "index": {
            "_index": "test",
            "_type": "_doc",
            "_id": "1",
            "_version": 1,
            "result": "created",
            "_shards": {
               "total": 2,
               "successful": 1,
               "failed": 0
            },
            "status": 201,
            "_seq_no" : 0,
            "_primary_term": 1
         }
      },
      {
         "delete": {
            "_index": "test",
            "_type": "_doc",
            "_id": "2",
            "_version": 1,
            "result": "not_found",
            "_shards": {
               "total": 2,
               "successful": 1,
               "failed": 0
            },
            "status": 404,
            "_seq_no" : 1,
            "_primary_term" : 2
         }
      },
      {
         "create": {
            "_index": "test",
            "_type": "_doc",
            "_id": "3",
            "_version": 1,
            "result": "created",
            "_shards": {
               "total": 2,
               "successful": 1,
               "failed": 0
            },
            "status": 201,
            "_seq_no" : 2,
            "_primary_term" : 3
         }
      },
      {
         "update": {
            "_index": "test",
            "_type": "_doc",
            "_id": "1",
            "_version": 2,
            "result": "updated",
            "_shards": {
                "total": 2,
                "successful": 1,
                "failed": 0
            },
            "status": 200,
            "_seq_no" : 3,
            "_primary_term" : 4
         }
      }
   ]
}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值