bootwiki-Elasticsearch教程

https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

Elasticsearch教程


Elasticsearch 是一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎,可以说 Lucene 是当今最先进,最高效的全功能开源搜索引擎框架。

Elasticsearch是基于Apache Lucene的搜索服务器。它由Shay Banon开发并于2010年发布。现在是由Elasticsearch BV负责维护。其最新版本是:5.2.0

Elasticsearch是一个实时分布式和开源的全文搜索和分析引擎。 它可以从RESTful Web服务接口访问,并使用模式少JSON(JavaScript对象符号)文档来存储数据。它是基于Java编程语言,这使Elasticsearch能够在不同的平台上运行。使用户能够以非常快的速度来搜索非常大的数据量。

Elasticsearch的特性

Elasticsearch的一般特性如下 -

  • Elasticsearch可扩展高达PB级的结构化和非结构化数据。
  • Elasticsearch可以用来替代MongoDB和RavenDB等做文档存储。
  • Elasticsearch使用非标准化来提高搜索性能。
  • Elasticsearch是受欢迎的企业搜索引擎之一,目前被许多大型组织使用,如Wikipedia,The Guardian,StackOverflow,GitHub等。
  • Elasticsearch是开放源代码,可在Apache许可证版本2.0下提供。

Elasticsearch的主要概念

Elasticsearch的主要概念如下 -

  • 节点 - 它指的是Elasticsearch的单个正在运行的实例。单个物理和虚拟服务器容纳多个节点,这取决于其物理资源的能力,如RAM,存储和处理能力。

  • 集群 - 它是一个或多个节点的集合。 集群为整个数据提供跨所有节点的集合索引和搜索功能。

  • 索引 - 它是不同类型的文档和文档属性的集合。索引还使用分片的概念来提高性能。 例如,一组文档包含社交网络应用的数据。

  • 类型/映射 - 它是共享同一索引中存在的一组公共字段的文档的集合。 例如,索引包含社交网络应用的数据,然后它可以存在用于用户简档数据的特定类型,另一类型可用于消息的数据,以及另一类型可用于评论的数据。

  • 文档 - 它是以JSON格式定义的特定方式的字段集合。每个文档都属于一个类型并驻留在索引中。每个文档都与唯一标识符(称为UID)相关联。

  • 碎片 - 索引被水平细分为碎片。这意味着每个碎片包含文档的所有属性,但包含的数量比索引少。水平分隔使碎片成为一个独立的节点,可以存储在任何节点中。主碎片是索引的原始水平部分,然后这些主碎片被复制到副本碎片中。

  • 副本 - Elasticsearch允许用户创建其索引和分片的副本。 复制不仅有助于在故障情况下增加数据的可用性,而且还通过在这些副本中执行并行搜索操作来提高搜索的性能。

Elasticsearch的优点

  • Elasticsearch是基于Java开发的,这使得它在几乎每个平台上都兼容。
  • Elasticsearch是实时的,换句话说,一秒钟后,添加的文档可以在这个引擎中搜索得到。
  • Elasticsearch是分布式的,这使得它易于在任何大型组织中扩展和集成。
  • 通过使用Elasticsearch中的网关概念,创建完整备份很容易。
  • 与Apache Solr相比,在Elasticsearch中处理多租户非常容易。
  • Elasticsearch使用JSON对象作为响应,这使得可以使用不同的编程语言调用Elasticsearch服务器。
  • Elasticsearch支持几乎大部分文档类型,但不支持文本呈现的文档类型。

Elasticsearch的缺点

  • Elasticsearch在处理请求和响应数据方面没有多语言和数据格式支持(仅在JSON中可用),与Apache Solr不同,Elasticsearch不可以使用CSV,XML等格式。

  • Elasticsearch也有一些伤脑的问题发生,虽然在极少数情况下才会发生。

Elasticsearch和RDBMS之间的比较

在Elasticsearch中,索引是类型的集合,因为数据库是RDBMS(关系数据库管理系统)中表的集合。每个表都是行的集合,就像每个映射都是JSON对象的Elasticsearch集合一样。

Elasticsearch关系数据库
索引 数据库
碎片 碎片
映射
字段 字段
JSON对象 元组

Elasticsearch环境安装配置


安装Elasticsearch的步骤如下 -

第1步 - 查看安装在计算机上的java的最低版本,它要求java 7或以上或最新的版本。可以通过执行以下操作进行检查 -

在Windows操作系统(OS)(使用命令提示符) -

java -version

在UNIX/Linux操作系统(使用终端) -

$ echo $JAVA_HOME

第2步 - 从 www.elastic.co 下载最新的 Elasticsearch,注意选择对应版本 -

  • 对于Windows操作系统,请下载ZIP文件。
  • 对于UNIX操作系统,请下载TAR文件。
  • 对于Debian操作系统,请下载DEB文件。
  • 对于Red Hat和其他Linux发行版,请下载RPM文件。
  • APT和Yum实用程序也可用于在许多Linux发行版中用来安装Elasticsearch。

第3步 - Elasticsearch的安装过程非常容易,下面介绍在不同的操作系统如何安装 -

  • Windows操作系统 − 解压缩zip包,并安装Elasticsearch。
  • UNIX操作系统 - 在任何位置提取tar文件,并安装Elasticsearch。
    $tar –xvf elasticsearch-5.2.0.tar.gz
    
  • 使用APT实用程序的Linux操作系统 -
    下载并安装公共签名密钥 -

    $ wget -qO - http://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
    

    保存存储库定义 -

    $ echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list
    

    运行更新 -

    $ sudo apt-get update
    

    现在就可以使用以下命令来安装了 -

    $ sudo apt-get install elasticsearch
    
  • 使用YUM实用程序的Debian Linux操作系统 -
    下载并安装公共签名密钥 -

    $ rpm --import http://packages.elastic.co/GPG-KEY-elasticsearch
    

    在“/etc/yum.repos.d/”目录中用.repo作为后缀在文件中添加以下文本。 例如,在elasticsearch.repo文件中,添加以下文本 -

    [elasticsearch-5.x]
    name = Elasticsearch repository for5.x packages
    baseurl = http://packages.elastic.co/elasticsearch/5.x/centos
    gpgcheck = 1
    gpgkey = http://packages.elastic.co/GPG-KEY-elasticsearch
    enabled = 1
    

    现在可以使用以下命令安装Elasticsearch:

    $ yum install elasticsearch
    

    第4步 - 进入到Elasticsearch主目录和bin文件夹。在Windows系统下可运行elasticsearch.bat文件,或者在UNIX rum Elasticsearch文件的情况下,可以使用命令提示符和通过终端执行相同操作。

在Windows中 -

> cd elasticsearch-5.1.0/bin
> elasticsearch

在Linux中 -

$ cd elasticsearch-5.1.0/bin
$ ./elasticsearch

注意 - 在Windows系统中,可能会收到错误,指出未设置JAVA_HOME,请将环境变量设置为“C:Program FilesJavajre1.8.0_65”或设置实际安装java的位置。

第5步 - Elasticsearch Web界面的默认端口是9200,或者可以通过更改bin目录中的elasticsearch.yml文件中的http.port字段值来更改。可以通过浏览http:// localhost:9200来检查服务器是否已启动并正在运行。如果没有问题,它将返回一个JSON对象,其中包含有关安装的Elasticsearch信息有以下方式 -

{
   "name" : "Brain-Child",
   "cluster_name" : "elasticsearch", "version" : {
      "number" : "5.1.0",
      "build_hash" : "72cd1f1a3eee09505e036106146dc1949dc5dc87",
      "build_timestamp" : "2015-11-18T22:40:03Z",
      "build_snapshot" : false,
      "lucene_version" : "5.3.1"
   },
   "tagline" : "You Know, for Search"
}

第6步 - 可以从 www.telerik.com 安装 fiddler2 作为 Elasticsearch 的前端。

  • fiddler2的配置窗口中,您可以点击Elasticsearch的地址添加索引,如果需要,那么类型/映射也使用HTTP POST方法,例如 -
  • 可以使用相同方式来搜索任何东西,只需在URL的结尾处添加“_search”关键字,并在请求正文中发送一个查询,例如 -

  • 可以通过将相同的URL放在地址栏中,并使用HTTP DELETE方法进行匹配来删除特定的索引或类型。

Elasticsearch入门教程

使用REST API与Sense

ElasticSearch的实例并运行,您可以使用localhost:9200,基于JSON的REST API与ElasticSearch进行通信。使用任何HTTP客户端来通信。在ElasticSearch自己的文档中,所有示例都使用curl。 但是,当使用API时也可使用图形客户端(如FiddlerRESTClient),这样操作起更方便直观一些。

更方便的是Chrome插件Sense。 Sense提供了一个专门用于使用ElasticSearch的REST API的简单用户界面。 它还具有许多方便的功能,例如:ElasticSearch的查询语法的自动完成功能以及curl格式的复制和粘贴请求,从而可以方便地在文档中运行示例。

我们将在本教程中使用sense来执行curl请求,建议安装Sense并使用它学习后续文章内容。

安装完成后,在Chrome的右上角找到Sense的图标。 第一次单击它运行Sense时,会为您准备一个非常简单的示例请求。如下图所示 -

上述请求将执行最简单的搜索查询,匹配服务器上所有索引中的所有文档。针对ElasticSearch运行,Sense提供的最简单的查询,在响应结果的数据中并没有查询到任何数据,因为没有任何索引。如下所示 -

{
   "took": 1,
   "timed_out": false,
   "_shards": {
      "total": 0,
      "successful": 0,
      "failed": 0
   },
   "hits": {
      "total": 0,
      "max_score": 0,
      "hits": []
   }
}

下一步我们来学习添加一些数据和索引,来修复这个问题。

文档管理(CRUD)

想要使用ElasticSearch,用于搜索第一步就是使用一些数据填充来索引,CRUD表“创建”或者“索引”。我们还将学习如何更新,读取和删除文档。

创建索引

在ElasticSearch索引中,对应于CRUD中的“创建”和“更新” - 如果对具有给定类型的文档进行索引,并且要插入原先不存在的ID。 如果具有相同类型和ID的文档已存在,则会被覆盖。

要索引第一个JSON对象,我们对REST API创建一个PUT请求到一个由索引名称,类型名称和ID组成的URL。 也就是:http://localhost:9200/<index>/<type>/[<id>]

索引和类型是必需的,而id部分是可选的。如果不指定IDElasticSearch会为我们生成一个ID。 但是,如果不指定id,应该使用HTTP的POST而不是PUT请求。

索引名称是任意的。如果服务器上没有此名称的索引,则将使用默认配置来创建一个索引。

至于类型名称,它也是任意的。 它有几个用途,包括:

  • 每种类型都有自己的ID空间。
  • 不同类型具有不同的映射(“模式”,定义属性/字段应如何编制索引)。
  • 搜索多种类型是可以的,并且也很常见,但很容易搜索一种或多种指定类型。

现在我们来索引一些内容! 可以把任何东西放到索引中,只要它可以表示为单个JSON对象。 在本教程中,使用索引和搜索电影的一个示例。这是一个经典的电影对象信息:

{
    "title": "The Godfather",
    "director": "Francis Ford Coppola",
    "year": 1972
}

要创建一个索引,这里使用索引的名称为“movies”,类型名称(“movie”)和id(“1”),并按照上述模式使用JSON对象在正文中进行请求。

curl -XPUT "http://localhost:9200/movies/movie/1" -d'
{
    "title": "The Godfather",
    "director": "Francis Ford Coppola",
    "year": 1972
}'

可以使用curl来执行它,也可以使用Sense。这里使用Sense,可以自己填充URL,方法和请求正文,或者您以复制上述curl示例,将光标置于Sense中的正文字段中写入上面的Json对象,然后按点击绿色小箭头来执行创建索引操作。如下图所示 -

执行请求后,可以看到接收到来自ElasticSearch响应的JSON对象。如下所示 -

{
   "_index": "movies",
   "_type": "movie",
   "_id": "1",
   "_version": 1,
   "result": "created",
   "_shards": {
      "total": 2,
      "successful": 1,
      "failed": 0
   },
   "created": true
}

响应对象包含有关索引操作的信息,例如它是否成功(“ok”)和文档ID,如果不指定则ElasticSearch会自己生成一个。

如果运行Sense提供的默认搜索请求(可以使用Sense中的“历史记录”按钮访问,因为确实已执行它)过了,就会看到返回有数据的结果。

{
   "took": 146,
   "timed_out": false,
   "_shards": {
      "total": 5,
      "successful": 5,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "movies",
            "_type": "movie",
            "_id": "1",
            "_score": 1,
            "_source": {
               "title": "The Godfather",
               "director": "Francis Ford Coppola",
               "year": 1972
            }
         }
      ]
   }
}

在上面返回结果中,看到的是搜索结果而不是错误或是空的结果。

更新索引

现在,在索引中有了一部电影信息,接下来来了解如何更新它,添加一个类型列表。要做到这一点,只需使用相同的ID索引它。使用与之前完全相同的索引请求,但类型扩展了JSON对象。

curl -XPUT "http://localhost:9200/movies/movie/1" -d'
{
    "title": "The Godfather",
    "director": "Francis Ford Coppola",
    "year": 1972,
    "genres": ["Crime", "Drama"]
}'

ElasticSearch的响应结果与前面的大体上一样,但有一点区别,结果对象中的_version属性的值为2,而不是1。响应结果如下 -

{
   "_index": "movies",
   "_type": "movie",
   "_id": "1",
   "_version": 2,
   "result": "updated",
   "_shards": {
      "total": 2,
      "successful": 1,
      "failed": 0
   },
   "created": false
}

版本号(_version)可用于跟踪文档已编入索引的次数。它的主要目的是允许乐观的并发控制,因为可以在索引请求中提供一个版本,如果提供的版本高于索引中的版本,ElasticSearch将只覆盖文档内容,ID值不变,版本号自动添加。

由ID获取文档/索引

上面已经学习了索引新文档以及更新存在的文档。还看到了一个简单搜索请求的示例。如果只是想检索一个具有已知ID的索引,一个方法是搜索索引中的文档。另一个简单而快速的方法是通过ID,使用GET来检索它。

简单的做法是向同一个URL发出一个GET请求,URL的ID部分是强制性的。通过ID从ElasticSearch中检索文档可发出URL的GET请求:http://localhost:9200/<index>/<type>/<id>

使用以下请求尝试获取电影信息:

curl -XGET "http://localhost:9200/movies/movie/1" -d''

执行结果如下所示 -

正如下图所看到的,结果对象包含与索引时所看到的类似的元数据,如索引,类型和版本信息。 最后最重要的是,它有一个名称为“_source”的属性,它包含实际获取的文档信息。

关于GET没有什么可说的,因为它很简单,继续最后删除操作。

删除文档

为了通过ID从索引中删除单个指定的文档,使用与获取索引文档相同的URL,只是这里将HTTP方法更改为DELETE

curl -XDELETE "http://localhost:9200/movies/movie/1" -d''

响应对象包含元数据方面的一些常见数据字段,以及名为“_found”的属性,表示文档确实已找到并且操作成功。

在执行DELETE调用后切换回GET,可以验证文档是否确实已删除。

搜索

在前面,已经介绍了在ElasticSearch索引中处理数据的基础知识,现在是时候进行核心功能的学习了。考虑到之前我们删除索引中的所有文档,所以,在进行搜索学习之前,需要一些添加一些示例数据。使用以下这些请求和数据对象来创建索引。

curl -XPUT "http://localhost:9200/movies/movie/1" -d'
{
    "title": "The Godfather",
    "director": "Francis Ford Coppola",
    "year": 1972,
    "genres": ["Crime", "Drama"]
}'

curl -XPUT "http://localhost:9200/movies/movie/2" -d'
{
    "title": "Lawrence of Arabia",
    "director": "David Lean",
    "year": 1962,
    "genres": ["Adventure", "Biography", "Drama"]
}'

curl -XPUT "http://localhost:9200/movies/movie/3" -d'
{
    "title": "To Kill a Mockingbird",
    "director": "Robert Mulligan",
    "year": 1962,
    "genres": ["Crime", "Drama", "Mystery"]
}'

curl -XPUT "http://localhost:9200/movies/movie/4" -d'
{
    "title": "Apocalypse Now",
    "director": "Francis Ford Coppola",
    "year": 1979,
    "genres": ["Drama", "War"]
}'

curl -XPUT "http://localhost:9200/movies/movie/5" -d'
{
    "title": "Kill Bill: Vol. 1",
    "director": "Quentin Tarantino",
    "year": 2003,
    "genres": ["Action", "Crime", "Thriller"]
}'

curl -XPUT "http://localhost:9200/movies/movie/6" -d'
{
    "title": "The Assassination of Jesse James by the Coward Robert Ford",
    "director": "Andrew Dominik",
    "year": 2007,
    "genres": ["Biography", "Crime", "Drama"]
}'

值得指出的是,ElasticSearch具有和端点(_bulk)用于用单个请求索引多个文档,但是这超出了本教程的范围,这里只保持简单,使用六个单独的请求学习。

_search端点

现在已经把一些电影信息放入了索引,可以通过搜索看看是否可找到它们。 为了使用ElasticSearch进行搜索,我们使用_search端点,可选择使用索引和类型。也就是说,按照以下模式向URL发出请求:<index>/<type>/_search。其中,indextype都是可选的。

换句话说,为了搜索电影,可以对以下任一URL进行POST请求:

因为我们只有一个单一的索引和单一的类型,所以怎么使用都不会有什么问题。为了简洁起见使用第一个URL。

搜索请求正文和ElasticSearch查询DSL

如果只是发送一个请求到上面的URL,我们会得到所有的电影信息。为了创建更有用的搜索请求,还需要向请求正文中提供查询。 请求正文是一个JSON对象,除了其它属性以外,它还要包含一个名称为“query”的属性,这就可使用ElasticSearch的查询DSL。

{
    "query": {
        //Query DSL here
    }
}

你可能想知道查询DSL是什么。它是ElasticSearch自己基于JSON的域特定语言,可以在其中表达查询和过滤器。想象ElasticSearch它像关系数据库的SQL。这里是ElasticSearch自己的文档解释它的一部分(英文好自己撸吧):

Think of the Query DSL as an AST of queries. Certain queries can contain other queries (like the bool query), other can contain filters (like the constant_score), and some can contain both a query and a filter (like the filtered). Each of those can contain any query of the list of queries or any filter from the list of filters, resulting in the ability to build quite complex (and interesting) queries. see more: http://www.elasticsearch.org/guide/reference/query-dsl/

基本自由文本搜索

查询DSL具有一长列不同类型的查询可以使用。 对于“普通”自由文本搜索,最有可能想使用一个名称为“查询字符串查询”。

查询字符串查询是一个高级查询,有很多不同的选项,ElasticSearch将解析和转换为更简单的查询树。如果忽略了所有的可选参数,并且只需要给它一个字符串用于搜索,它可以很容易使用。

现在尝试在两部电影的标题中搜索有“kill”这个词的电影信息:

curl -XPOST "http://localhost:9200/_search" -d'
{
    "query": {
        "query_string": {
            "query": "kill"
        }
    }
}'

执行上面的请求并查看结果,如下所示 -

正如预期的,得到两个命中结果,每个电影的标题中都带有“kill”单词。再看看另一种情况,在特定字段中搜索。

指定搜索的字段

在前面的例子中,使用了一个非常简单的查询,一个只有一个属性“query”的查询字符串查询。 如前所述,查询字符串查询有一些可以指定设置,如果不使用,它将会使用默认的设置值。

这样的设置称为“fields”,可用于指定要搜索的字段列表。如果不使用“fields”字段,ElasticSearch查询将默认自动生成的名为“_all”的特殊字段,来基于所有文档中的各个字段匹配搜索。

为了做到这一点,修改以前的搜索请求正文,以便查询字符串查询有一个fields属性用来要搜索的字段数组:

curl -XPOST "http://localhost:9200/_search" -d'
{
    "query": {
        "query_string": {
            "query": "ford",
            "fields": ["title"]
        }
    }
}'

执行上面查询它,看看会有什么结果(应该只匹配到 1 行数据):

正如预期的得到一个命中,电影的标题中的单词“ford”。现在,从查询中移除fields属性,应该能匹配到 3 行数据:

过滤

前面已经介绍了几个简单的自由文本搜索查询。现在来看看另一个示例,搜索“drama”,不明确指定字段,如下查询 -

curl -XPOST "http://localhost:9200/_search" -d'
{
    "query": {
        "query_string": {
            "query": "drama"
        }
    }
}'

因为在索引中有五部电影在_all字段(从类别字段)中包含单词“drama”,所以得到了上述查询的5个命中。 现在,想象一下,如果我们想限制这些命中为只是1962年发布的电影。要做到这点,需要应用一个过滤器,要求“year”字段等于1962

要添加过滤器,修改搜索请求正文,以便当前的顶级查询(查询字符串查询)包含在过滤的查询中:

{
    "query": {
        "filtered": {
            "query": {
                "query_string": {
                    "query": "drama"
                }
            },
            "filter": {
                //Filter to apply to the query
            }
        }
    }
}

过滤的查询是具有两个属性(queryfilter)的查询。执行时,它使用过滤器过滤查询的结果。要完成这样的查询还需要添加一个过滤器,要求year字段的值为1962

ElasticSearch查询DSL有各种各样的过滤器可供选择。对于这个简单的情况,某个字段应该匹配一个特定的值,一个条件过滤器就能很好地完成工作。

"filter": {
    "term": { "year": 1962 }
}

完整的搜索请求如下所示:

curl -XPOST "http://localhost:9200/_search" -d'
{
    "query": {
        "filtered": {
            "query": {
                "query_string": {
                    "query": "drama"
                }
            },
            "filter": {
                "term": { "year": 1962 }
            }
        }
    }
}'

当执行上面请求,只得到两个命中,这个两个命中的数据的 year 字段的值都是等于 1962

无需查询即可进行过滤

在上面的示例中,使用过滤器限制查询字符串查询的结果。如果想要做的是应用一个过滤器呢? 也就是说,我们希望所有电影符合一定的标准。

在这种情况下,我们仍然在搜索请求正文中使用“query”属性。但是,我们不能只是添加一个过滤器,需要将它包装在某种查询中。

一个解决方案是修改当前的搜索请求,替换查询字符串 query 过滤查询中的match_all查询,这是一个查询,只是匹配一切。类似下面这个:

curl -XPOST "http://localhost:9200/_search" -d'
{
    "query": {
        "filtered": {
            "query": {
                "match_all": {
                }
            },
            "filter": {
                "term": { "year": 1962 }
            }
        }
    }
}'

另一个更简单的方法是使用常数分数查询:

curl -XPOST "http://localhost:9200/_search" -d'
{
    "query": {
        "constant_score": {
            "filter": {
                "term": { "year": 1962 }
            }
        }
    }
}'

Elasticsearch填充


在本节中,我们将向Elasticsearch添加一些索引,映射和数据。此数据将用于本教程中解释的示例中。

创建索引

POST http://localhost:9200/schools

请求正文
它可以包含索引特定的设置,但是现在,它的默认设置为空。

响应

{"acknowledged": true}

这意味着创建索引成功

创建映射和添加数据

Elasticsearch将根据请求体中提供的数据自动创建映射,我们将使用其批量功能在此索引中添加多个JSON对象。

POST http://localhost:9200/schools/_bulk

请求体

{
   "index":{
      "_index":"schools", "_type":"school", "_id":"1"
   }
}
{
   "name":"Central School", "description":"CBSE Affiliation", "street":"Nagan",
   "city":"paprola", "state":"HP", "zip":"176115", "location":[31.8955385, 76.8380405],
   "fees":2000, "tags":["Senior Secondary", "beautiful campus"], "rating":"3.5"
}
{
   "index":{
      "_index":"schools", "_type":"school", "_id":"2"
   }
}
{
   "name":"Saint Paul School", "description":"ICSE 
   Afiliation", "street":"Dawarka", "city":"Delhi", "state":"Delhi", "zip":"110075",
   "location":[28.5733056, 77.0122136], "fees":5000,
   "tags":["Good Faculty", "Great Sports"], "rating":"4.5"
}
{
   "index":{"_index":"schools", "_type":"school", "_id":"3"}
}
{
   "name":"Crescent School", "description":"State Board Affiliation", "street":"Tonk Road", 
   "city":"Jaipur", "state":"RJ", "zip":"176114","location":[26.8535922, 75.7923988],
   "fees":2500, "tags":["Well equipped labs"], "rating":"4.5"
}

响应结果 -

{
   "took":328, "errors":false,"items":[
      {
         "index":{
            "_index":"schools", "_type":"school", "_id":"1", "_version":1, "_shards":{
               "total":2, "successful":1, "failed":0
            }, "status":201
         }
      },

      {
         "index":{
            "_index":"schools", "_type":"school", "_id":"2", "_version":1, "_shards":{
               "total":2, "successful":1, "failed":0
            }, "status":201
         }
      },

      {
         "index":{
            "_index":"schools", "_type":"school", "_id":"3", "_version":1, "_shards":{
               "total":2, "successful":1, "failed":0
            }, "status":201
         }
      }
   ]
}

添加另一个索引

创建索引

POST http://localhost:9200/schools_gov

请求正文

它可以包含索引特定的设置,但现在它的默认设置为空。

响应

{"acknowledged": true} (This means index is created)

创建映射和添加数据

POST http://localhost:9200/schools_gov/_bulk

请求正文

{
   "index":{
      "_index":"schools_gov", "_type":"school", "_id":"1"
   }
}
{
   "name":"Model School", "description":"CBSE Affiliation", "street":"silk city",
   "city":"Hyderabad", "state":"AP", "zip":"500030", "location":[17.3903703, 78.4752129],
   "fees":200, "tags":["Senior Secondary", "beautiful campus"], "rating":"3"
}
{
   "index":{
      "_index":"schools_gov", "_type":"school", "_id":"2"
   }
}
{
   "name":"Government School", "description":"State Board Affiliation",
   "street":"Hinjewadi", "city":"Pune", "state":"MH", "zip":"411057",
   "location": [18.599752, 73.6821995], "fees":500, "tags":["Great Sports"], "rating":"4"
}

响应

{
   "took":179, "errors":false, "items":[
      {
        "index":{
           "_index":"schools_gov", "_type":"school", "_id":"1", "_version":1, "_shards":{
              "total":2, "successful":1, "failed":0
            }, "status":201
         }
      },

      {
         "index":{
            "_index":"schools_gov", "_type":"school", "_id":"2", "_version":1, "_shards":{
               "total":2, "successful":1, "failed":0
            }, "status":201
         }
      }
   ]
}

Elasticsearch版本之间迁移


在任何系统或软件中,当我们升级到较新版本时,需要按照几个步骤来维护应用程序设置,配置,数据和其他事情。 这些步骤是使应用程序在新系统中保持稳定或保持数据的完整性(防止数据损坏)所必需的。

以下是升级Elasticsearch的步骤 -

  • http://www.elastic.co/ 阅读了解如何更改文档。
  • 在非生产环境(如UAT,E2E,SIT或DEV环境)中测试升级版本。
  • 如果没有数据备份,则无法回滚到上一个Elasticsearch版本。 建议在升级到更高版本之前进行数据备份。
  • 可以使用完全群集重新启动或滚动升级进行升级。 滚动升级适用于新版本(适用于2.x和更高版本)。当您使用滚动升级方法进行迁移时,不要中断服务。
旧版新版升级方法
0.90.x 2.x 完全群集重新启动
1.x 2.x 完全群集重新启动
2.x 2.y 滚动升级(y> x)
  • 在迁移前进行数据备份,并按照说明执行备份过程。 快照和恢复模块可用于进行备份。此模块可用于创建索引或完整集群的快照,并可存储在远程存储库中。

快照和还原模块

在开始备份过程之前,需要在Elasticsearch中注册快照存储库。

PUT /_snapshot/backup1
{
   "type": "fs", "settings": {
      ... repository settings ...
   }
}

注意 - 上面的文本是对http://localhost:9200/_snapshot/backup1的HTTP PUT请求(可以是远程服务器的IP地址,而不是localhost)。其余的文本是请求正文。可以使用fiddler2和Windows中的其他网络工具。

我们使用共享文件系统(类型:fs)进行备份; 它需要在每个主节点和数据节点中注册。只需要添加具有备份存储库路径的path.repo变量作为值。

添加存储库路径后,需要重新启动节点,然后可以通过执行以下命令来执行注册 -

PUT http://localhost:9200/_snapshot/backup1
{
   "type": "fs", "settings": {
      "location": "/mount/backups/backup1", "compress": true
   }
}

完全群集重新启动

此升级过程包括以下步骤 -

第1步 - 禁用碎片分配程序,并关闭节点。

PUT http://localhost:9200/_cluster/settings
{
   "persistent": {
      "cluster.routing.allocation.enable": "none"
   }
}

在升级0.90.x1.x的情况下使用以下请求 -

PUT http://localhost:9200/_cluster/settings
{
   "persistent": {
      "cluster.routing.allocation.disable_allocation": false,
      "cluster.routing.allocation.enable": "none"
   }
}

第2步 - 对Elasticsearch进行同步刷新 -

POST http://localhost:9200/_flush/synced

第3步 - 在所有节点上,终止所有 elastic 服务。
第4步 - 在每个节点上执行以下操作 -

  • 在Debian或Red Hat节点中 - 可以使用rmp或dpkg通过安装新软件包来升级节点。 不要覆盖配置文件。
  • 在Windows(zip文件)或UNIX(tar文件) - 提取新版本,而不覆盖config目录。 您可以从旧安装复制文件或可以更改path.confpath.data

第5步 - 从群集中的主节点(node.master设置为truenode.data设置为false的节点)开始重新启动节点。等待一段时间以建立群集。可以通过监视日志或使用以下请求进行检查 -

GET _cat/health or http://localhost:9200/_cat/health
GET _cat/nodes or http://localhost:9200/_cat/health

第6步 - 使用GET _cat/health请求监视集群的形成进度,并等待黄色响应,响应将是这样 -

1451295971 17:46:11 elasticsearch yellow 1 1 5 5 0 0 5 0 - 50.0%

第6步 - 启用分片分配过程,这是在第1步中禁用的,使用以下请求 -

PUT http://localhost:9200/_cluster/settings
{
   "persistent": {
      "cluster.routing.allocation.enable": "all"
   }
}

在将0.90.x升级到1.x的情况下,请使用以下请求 -

PUT http://localhost:9200/_cluster/settings
{
   "persistent": {
      "cluster.routing.allocation.disable_allocation": true,
      "cluster.routing.allocation.enable": "all"
   }
}

滚动升级

它与完全群集重新启动相同,但第3步除外。在此,停止一个节点并进行升级。升级后,重新启动节点并对所有节点重复这些步骤。 启用分片分配过程后,可以通过以下请求监视:

GET http://localhost:9200/_cat/recovery

Elasticsearch API约定


web中的应用编程接口(API)是一组函数调用或其他编程指令以访问该特定web应用中的软件组件。 例如,Facebook API帮助开发者通过从Facebook访问数据或其他功能来创建应用程序; 它可以是出生日期或状态更新。

Elasticsearch提供了一个REST API,通过HTTP通过JSON访问。 Elasticsearch使用以下约定 -

多索引

API中的大多数操作(主要是搜索和其他操作)用于一个或多个索引。 这有助于用户通过只执行一次查询来搜索多个位置或所有可用数据。 许多不同的符号用于在多个索引中执行操作。 我们将在本节讨论其中的一些。

逗号分隔符号

POST http://localhost:9200/index1,index2,index3/_search

请求正文

{
   "query":{
      "query_string":{
         "query":"any_string"
      }
   }
}

响应

来自index1index2index3的JSON对象,其中包含any_string

所有索引的_all关键字

POST http://localhost:9200/_all/_search

请求正文

{
   "query":{
      "query_string":{
         "query":"any_string"
      }
   }
}

响应

来自所有索引的JSON对象,并且有any_string

通配符(*,+, - )

POST http://localhost:9200/school*/_search

请求正文

{
   "query":{
      "query_string":{
         "query":"CBSE"
      }
   }
}

响应
来自所有索引的JSON对象,从school 开始,有CBSE。

或者,也可以使用以下代码 -

POST http://localhost:9200/school*,-schools_gov /_search

请求正文

{
   "query":{
      "query_string":{
         "query":"CBSE"
      }
   }
}

响应

来自所有索引的JSON对象,它们以“school”开头,但不是schools_gov并且在其中有CBSE。
还有一些URL查询字符串参数 -

  • ignore_unavailable - 如果URL中存在的一个或多个索引不存在,则不会发生错误或操作不会停止。 例如,schools 索引存在,但book_shops不存在 -
    POST http://localhost:9200/school*,book_shops/_search
    

请求正文

{
   "query":{
      "query_string":{
         "query":"CBSE"
      }
   }
}

响应

{
   "error":{
      "root_cause":[{
         "type":"index_not_found_exception", "reason":"no such index",
         "resource.type":"index_or_alias", "resource.id":"book_shops", 
         "index":"book_shops"
      }],

      "type":"index_not_found_exception", "reason":"no such index",
      "resource.type":"index_or_alias", "resource.id":"book_shops", 
      "index":"book_shops"

   },"status":404
}

看看下面的代码 -

POST http://localhost:9200/school*,book_shops/_search?ignore_unavailable = true

请求正文

{
   "query":{
      "query_string":{
         "query":"CBSE"
      }
   }
}

响应(无错误)
来自所有索引的JSON对象,从 school 开始,有CBSE

allow_no_indices

如果带有通配符的网址没有索引,这个参数是true值时将防止错误。

例如,不是以schools_pri开头的索引 -

POST
http://localhost:9200/schools_pri*/_search?allow_no_indices = true

请求正文

{
   "query":{
      "match_all":{}
   }
}

响应(无错误)

{
   "took":1,"timed_out": false, "_shards":{"total":0, "successful":0, "failed":0}, 
   "hits":{"total":0, "max_score":0.0, "hits":[]}
}

expand_wildcards

此参数确定通配符是否需要扩展为打开索引或闭合索引或两者。 此参数的值可以是打开和关闭或无和全部。

例如,关闭索引schools -

POST http://localhost:9200/schools/_close

响应

{"acknowledged":true}

看看下面的代码 -

POST http://localhost:9200/school*/_search?expand_wildcards = closed

请求正文

{
   "query":{
      "match_all":{}
   }
}

响应

{
   "error":{
      "root_cause":[{
         "type":"index_closed_exception", "reason":"closed", "index":"schools"
      }],

      "type":"index_closed_exception", "reason":"closed", "index":"schools"
   }, "status":403
}

日期索引名称中的数学支持

Elasticsearch提供了根据日期和时间搜索索引的功能。我们需要以特定格式指定日期和时间。 例如,accountdetail-2015.12.30,索引将存储2015年12月30日的银行帐户详细信息。可以执行数学操作以获取特定日期或日期和时间范围的详细信息。

日期数字索引名称的格式 -

<static_name{date_math_expr{date_format|time_zone}}>
http://localhost:9200/<accountdetail-{now-2d{YYYY.MM.dd|utc}}>/_search

static_name是表达式的一部分,在每个日期数学索引(如帐户详细信息)中保持相同。 date_math_expr包含动态确定日期和时间的数学表达式,如now-2ddate_format包含日期在索引中写入的格式,如YYYY.MM.dd。 如果今天的日期是2015年12月30日,则<accountdetail- {now-2d {YYYY.MM.dd}}>将返回accountdetail-2015.12.28

表达式解析为
<accountdetail-{now-d}> accountdetail-2016.12.29
<accountdetail-{now-M}> accountdetail-2015.11.30
<accountdetail-{now{YYYY.MM}}> accountdetail-2015.12

现在将看到Elasticsearch中可用于获取指定格式的响应的一些常见选项。

美化结果

可以通过附加一个网址查询参数(即pretty = true),获得格式正确的JSON对象的响应。

POST http://localhost:9200/schools/_search?pretty = true

请求正文

{
   "query":{
      "match_all":{}
   }
}

响应

……………………..
{
   "_index" : "schools", "_type" : "school", "_id" : "1", "_score" : 1.0,
   "_source":{
      "name":"Central School", "description":"CBSE Affiliation", 
      "street":"Nagan", "city":"paprola", "state":"HP", "zip":"176115",
      "location": [31.8955385, 76.8380405], "fees":2000, 
      "tags":["Senior Secondary", "beautiful campus"], "rating":"3.5"
   }
}    
………………….

人类可读输出

此选项可以将统计响应更改为人类可读的形式(如果human = true)或计算机可读形式(如果human = false)。 例如,如果human = true那么distance_kilometer = 20KM,如果human = false那么distance_meter = 20000,则是响应需要被另一个计算机程序使用。

响应过滤
可以通过将其添加到field_path参数中来过滤对较少字段的响应。 例如,

POST http://localhost:9200/schools/_search?filter_path = hits.total

请求正文

{
   "query":{
      "match_all":{}
   }
}

响应

{"hits":{"total":3}}

Elasticsearch文档API


Elasticsearch提供单文档API和多文档API,其中API调用分别针对单个文档和多个文档。

索引API

当使用特定映射对相应索引发出请求时,它有助于在索引中添加或更新JSON文档。 例如,以下请求将JSON对象添加到索引学校和学校映射下。

POST http://localhost:9200/schools/school/4

请求正文

{
   "name":"City School", "description":"ICSE", "street":"West End", "city":"Meerut", 
   "state":"UP", "zip":"250002", "location":[28.9926174, 77.692485], "fees":3500, 
   "tags":["fully computerized"], "rating":"4.5"
}

响应

{
   "_index":"schools", "_type":"school", "_id":"4", "_version":1,
   "_shards":{"total":2, "successful":1,"failed":0}, "created":true
}

自动索引创建

当请求将JSON对象添加到特定索引时,如果该索引不存在,那么此API会自动创建该索引以及该特定JSON对象的基础映射。 可以通过将以下参数的值更改为false来禁用此功能,这个值是存在于elasticsearch.yml文件中,打开elasticsearch.yml文件设置如下 。

action.auto_create_index:false
index.mapper.dynamic:false

还可以限制自动创建索引,其中通过更改以下参数的值只允许指定模式的索引名称 -

action.auto_create_index:+acc*,-bank*

(其中+表示允许, - 表示不允许)

版本控制

Elasticsearch还提供版本控制功能。我们可以使用版本查询参数指定特定文档的版本。 例如,

POST http://localhost:9200/schools/school/1?version = 1

请求正文

{
   "name":"Central School", "description":"CBSE Affiliation", "street":"Nagan",
   "city":"paprola", "state":"HP", "zip":"176115", "location":[31.8955385, 76.8380405],
   "fees":2200, "tags":["Senior Secondary", "beautiful campus"], "rating":"3.3"
}

响应内容

{
   "_index":"schools", "_type":"school", "_id":"1", "_version":2,
   "_shards":{"total":2, "successful":1,"failed":0}, "created":false
}

有两种最重要的版本控制类型: 内部版本控制是以1开头的默认版本,每次更新都会增加,包括删除。版本号可以在外部设置。要启用此功能,我们需要将version_type设置为external

版本控制是一个实时过程,它不受实时搜索操作的影响。

操作类型

操作类型用于强制创建操作,这有助于避免覆盖现有文档。

POST http://localhost:9200/tutorials/chapter/1?op_type = create

请求正文

{
   "Text":"this is chapter one"
}

响应内容

{
   "_index":"tutorials", "_type":"chapter", "_id":"1", "_version":1,
   "_shards":{"total":2, "successful":1, "failed":0}, "created":true
}

自动生成ID

当在索引操作中未指定ID时,Elasticsearch自动为文档生成ID

父级和子级

可以通过在父URL查询参数中传递父文档的ID来定义任何文档的父级。

POST http://localhost:9200/tutorials/article/1?parent = 1

请求正文

{
   "Text":"This is article 1 of chapter 1"
}

注意 - 如果在执行此示例时遇到异常,请通过在索引中添加以下内容来重新创建索引。

{
   "mappings": {
      "chapter": {},
      "article": {
         "_parent": {
            "type": "chapter"
         }
      }
   }
}

超时

默认情况下,索引操作将在主分片上最多等待1分钟,超过后就会失败并响应错误。 可以通过将值传递给timeout参数来显式更改这个超时值。

POST http://localhost:9200/tutorials/chapter/2?timeout = 3m

请求正文

{
   "Text":"This is chapter 2 waiting for primary shard for 3 minutes"
}

获取API

API通过对特定文档执行get请求来帮助提取JSON对象。 例如,

GET http://localhost:9200/schools/school/1

响应

{
   "_index":"schools", "_type":"school", "_id":"1", "_version":2,
   "found":true, "_source":{
      "name":"Central School", "description":"CBSE Affiliation", 
      "street":"Nagan", "city":"paprola", "state":"HP", "zip":"176115",
      "location":[31.8955385,76.8380405], "fees":2200, 
      "tags":["Senior Secondary", "beautiful campus"], "rating":"3.3"
   }
}
  • 这个操作是实时的,不受索引刷新率的影响。
  • 还可以指定版本,然后Elasticsearch将仅提取该版本的文档。
  • 还可以在请求中指定_all,以便Elasticsearch可以在每种类型中搜索该文档ID,并且它将返回第一个匹配的文档。
  • 还可以从该特定文档的结果中指定所需的字段。
GET http://localhost:9200/schools/school/1?fields = name,fees

响应

……………………..
"fields":{
   "name":["Central School"], "fees":[2200]
}
……………………..

还可以通过在get请求中添加_source字段来获取结果中的源部分。

GET http://localhost:9200/schools/school/1/_source

响应

{
   "name":"Central School", "description":"CBSE Afiliation", "street":"Nagan",
   "city":"paprola", "state":"HP", "zip":"176115", "location":[31.8955385, 76.8380405],
   "fees":2200, "tags":["Senior Secondary", "beatiful campus"], "rating":"3.3"
}

还可以在通过将 refresh 参数设置为true进行get操作之前刷新碎片。

删除API

可以通过向Elasticsearch发送HTTP DELETE请求来删除指定的索引,映射或文档。 例如,

DELETE http://localhost:9200/schools/school/4

响应

{
   "found":true, "_index":"schools", "_type":"school", "_id":"4", "_version":2,
   "_shards":{"total":2, "successful":1, "failed":0}
}
  • 可以指定文档的版本以删除指定的版本。
  • 可以指定路由参数以删除指定用户的文档,如果文档不属于该特定用户,则操作将失败。
  • 在此操作中,可以像GET API那样指定刷新(refresh)和超时(timeout)选项。

更新API

脚本用于执行此操作,版本控制用于确保在获取和重建索引期间没有发生更新。 例如,使用下面脚本更新学校的费用 -

POST http://localhost:9200/schools_gov/school/1/_update

请求正文

{
   "script":{
      "inline": "ctx._source.fees+ = inc", "params":{
         "inc": 500
      }
   }
}

响应结果

{
   "_index":"schools_gov", "_type":"school", "_id":"1", "_version":2,
   "_shards":{"total":2, "successful":1, "failed":0}
}

注意 - 如果获取脚本异常,建议在elastcisearch.yml中添加以下行

script.inline: on
script.indexed: on

可以通过向更新的文档发送获取请求来检查更新。

GET http://localhost:9200/schools_gov/school/1

多获取API

它具有相同的功能,如GET API,但此get请求可以返回多个文档。使用doc数组来指定需要提取的所有文档的索引,类型和ID。

POST http://localhost:9200/_mget

请求正文

{
   "docs":[
      {
         "_index": "schools", "_type": "school", "_id": "1"
      },

      {
         "_index":"schools_gev", "_type":"school", "_id": "2"
      }
   ]
}

响应结果

{
   "docs":[
      {
         "_index":"schools", "_type":"school", "_id":"1",
         "_version":1, "found":true, "_source":{
            "name":"Central School", "description":"CBSE Afiliation",
            "street":"Nagan", "city":"paprola", "state":"HP", "zip":"176115",
            "location":[31.8955385,76.8380405], "fees":2000, 
            "tags":["Senior Secondary", "beatiful campus"], "rating":"3.5"
         }
      },

      {
         "_index":"schools_gev", "_type":"school", "_id":"2", "error":{

            "root_cause":[{
               "type":"index_not_found_exception", "reason":"no such index", 
               "index":"schools_gev"
            }],

            "type":"index_not_found_exception", "reason":"no such index", 
            "index":"schools_gev"
         }
      }
   ]
}

批量API

此API用于通过在单个请求中进行多个索引/删除操作来批量上传或删除JSON对象。 需要添加“_bulk”关键字来调用此API。此API的示例已在Elasticsearch填充文章中执行。所有其他功能与GET API相同。

Elasticsearch搜索API


此API用于在Elasticsearch中搜索内容。 用户可以通过发送具有查询字符串的获取请求作为参数或在请求的消息正文中的查询来进行搜索。所有的搜索API都是多索引,多类型。

多索引

Elasticsearch允许我们搜索存在于所有索引或一些特定索引中的文档。 例如,如果我们需要搜索名称包含central的所有文档。

GET http://localhost:9200/_search?q = name:central

响应

{
   "took":78, "timed_out":false, "_shards":{"total":10, "successful":10, "failed":0},
   "hits":{
      "total":1, "max_score":0.19178301, "hits":[{
         "_index":"schools", "_type":"school", "_id":"1", "_score":0.19178301,
         "_source":{
            "name":"Central School", "description":"CBSE Affiliation", 
            "street":"Nagan", "city":"paprola", "state":"HP", "zip":"176115",
            "location":[31.8955385, 76.8380405], "fees":2000, 
            "tags":["Senior Secondary", "beautiful campus"], "rating":"3.5"
         }
      }]
   }
}

或者,同样地我们可以在schoolsschools_gov索引中搜索 -

多类型

还可以在所有类型或某种指定类型的索引中搜索所有文档。 例如,

Get http://localhost:9200/schools/_search?q = tags:sports

响应

{
   "took":16, "timed_out":false, "_shards":{"total":5, "successful":5, "failed":0},
   "hits":{
      "total":1, "max_score":0.5, "hits":[{
         "_index":"schools", "_type":"school", "_id":"2", "_score":0.5,
         "_source":{
            "name":"Saint Paul School", "description":"ICSE Afiliation", 
            "street":"Dawarka", "city":"Delhi", "state":"Delhi", "zip":"110075", 
            "location":[28.5733056, 77.0122136], "fees":5000, 
            "tags":["Good Faculty", "Great Sports"], "rating":"4.5"
         }
      }]
   }
}

URI搜索

如下这些参数可以使用统一资源标识符在搜索操作中传递 -

编号参数说明
1 Q 此参数用于指定查询字符串。
2 lenient 基于格式的错误可以通过将此参数设置为true来忽略。默认情况下为false
3 fields 此参数用于在响应中选择返回字段。
4 sort 可以通过使用这个参数获得排序结果,这个参数的可能值是fieldNamefieldName:ascfieldname:desc
5 timeout 使用此参数限定搜索时间,响应只包含指定时间内的匹配。默认情况下,无超时。
6 terminate_after 可以将响应限制为每个分片的指定数量的文档,当到达这个数量以后,查询将提前终止。 默认情况下不设置terminate_after
7   从命中的索引开始返回。默认值为0
8 size 它表示要返回的命中数。默认值为10

请求正文搜索

还可以在请求正文中使用查询DSL来指定查询,并且在前面的章节中已经给出了很多示例,

POST http://localhost:9200/schools/_search

请求正文

{
   "query":{
      "query_string":{
         "query":"up"
      }
   }
}

响应

……………………………………………….
{
   "_source":{
      "name":"City School", "description":"ICSE", "street":"West End",
      "city":"Meerut", "state":"UP", "zip":"250002", "location":[28.9926174, 77.692485],
      "fees":3500, "tags":["Well equipped labs"],"rating":"4.5"
   }
}
……………………………………………….

Elasticsearch聚合


框架集合由搜索查询选择的所有数据。框架中包含许多构建块,有助于构建复杂的数据描述或摘要。聚合的基本结构如下所示 -

"aggregations" : {
   "<aggregation_name>" : {
      "<aggregation_type>" : {
         <aggregation_body>
      }

      [,"meta" : { [<meta_data_body>] } ]?
      [,"aggregations" : { [<sub_aggregation>]+ } ]?
   }
}

有以下不同类型的聚合,每个都有自己的目的 -

指标聚合

这些聚合有助于从聚合文档的字段值计算矩阵,并且某些值可以从脚本生成。
数字矩阵或者是平均聚合的单值,或者是像stats一样的多值。

平均聚合

此聚合用于获取聚合文档中存在的任何数字字段的平均值。 例如,

POST http://localhost:9200/schools/_search

请求正文

{
   "aggs":{
      "avg_fees":{"avg":{"field":"fees"}}
   }
}

响应

{
   "took":44, "timed_out":false, "_shards":{"total":5, "successful":5, "failed":0},
   "hits":{
      "total":3, "max_score":1.0, "hits":[
         {
            "_index":"schools", "_type":"school", "_id":"2", "_score":1.0,
            "_source":{
               "name":"Saint Paul School", "description":"ICSE Affiliation",
               "street":"Dawarka", "city":"Delhi", "state":"Delhi", 
               "zip":"110075", "location":[28.5733056, 77.0122136], "fees":5000, 
               "tags":["Good Faculty", "Great Sports"], "rating":"4.5"
            }
         },

         {
            "_index":"schools", "_type":"school", "_id":"1", "_score":1.0,
            "_source":{
               "name":"Central School", "description":"CBSE Affiliation",
               "street":"Nagan", "city":"paprola", "state":"HP", "zip":"176115",
               "location":[31.8955385, 76.8380405], "fees":2200, 
               "tags":["Senior Secondary", "beautiful campus"], "rating":"3.3"
            }
         },

         {
            "_index":"schools", "_type":"school", "_id":"3", "_score":1.0,
            "_source":{
               "name":"Crescent School", "description":"State Board Affiliation",
               "street":"Tonk Road", "city":"Jaipur", "state":"RJ", 
               "zip":"176114", "location":[26.8535922, 75.7923988], "fees":2500, 
               "tags":["Well equipped labs"], "rating":"4.5"
            }
         }
      ]
   }, "aggregations":{"avg_fees":{"value":3233.3333333333335}}
}

如果该值不存在于一个或多个聚合文档中,则默认情况下将忽略该值。您可以在聚合中添加缺少的字段,将缺少值视为默认值。

{
   "aggs":{
      "avg_fees":{
         "avg":{
            "field":"fees"
            "missing":0
         }
      }
   }
}

基数聚合

此聚合给出特定字段的不同值的计数。 例如,

POST http://localhost:9200/schools*/_search

请求正文

{
   "aggs":{
      "distinct_name_count":{"cardinality":{"field":"name"}}
   }
}

响应

………………………………………………
{
   "name":"Government School", "description":"State Board Afiliation",
   "street":"Hinjewadi", "city":"Pune", "state":"MH", "zip":"411057",
   "location":[18.599752, 73.6821995], "fees":500, "tags":["Great Sports"], 
   "rating":"4"
},

{
   "_index":"schools_gov", "_type": "school", "_id":"1", "_score":1.0,
   "_source":{
      "name":"Model School", "description":"CBSE Affiliation", "street":"silk city",
      "city":"Hyderabad", "state":"AP", "zip":"500030", 
      "location":[17.3903703, 78.4752129], "fees":700, 
      "tags":["Senior Secondary", "beautiful campus"], "rating":"3"
   }
}, "aggregations":{"disticnt_name_count":{"value":3}}
………………………………………………

注 - 基数的值为3,因为名称 - Government, School 和 Model中有三个不同的值。

扩展统计聚合

此聚合生成聚合文档中特定数字字段的所有统计信息。 例如,

POST http://localhost:9200/schools/school/_search

请求正文

{
   "aggs" : {
      "fees_stats" : { "extended_stats" : { "field" : "fees" } }
   }
}

响应

{
   "aggregations":{
      "fees_stats":{
         "count":3, "min":2200.0, "max":5000.0, 
         "avg":3233.3333333333335, "sum":9700.0,
         "sum_of_squares":3.609E7, "variance":1575555.555555556, 
         "std_deviation":1255.2113589175156,

         "std_deviation_bounds":{
            "upper":5743.756051168364, "lower":722.9106154983024
         }
      }
   }
}

最大聚合

此聚合查找聚合文档中特定数字字段的最大值。 例如,

POST http://localhost:9200/schools*/_search

请求正文

{
   "aggs" : {
      "max_fees" : { "max" : { "field" : "fees" } }
   }
}

响应

{
   aggregations":{"max_fees":{"value":5000.0}}
}

最小聚合

此聚合查找聚合文档中特定数字字段的最小值。 例如,

POST http://localhost:9200/schools*/_search

请求正文

{
   "aggs" : {
      "min_fees" : { "min" : { "field" : "fees" } }
   }
}

响应

"aggregations":{"min_fees":{"value":500.0}}

总和聚合

此聚合计算聚合文档中特定数字字段的总和。 例如,

POST http://localhost:9200/schools*/_search

请求正文

{
   "aggs" : {
      "total_fees" : { "sum" : { "field" : "fees" } }
   }
}

响应

"aggregations":{"total_fees":{"value":10900.0}}

在特殊情况下使用的一些其他度量聚合,例如地理边界聚集和用于地理位置的地理中心聚集。

桶聚合

这些聚合包含用于具有标准的不同类型的桶聚合,该标准确定文档是否属于某一个桶。桶聚合已经在下面描述 -

子聚集

此存储桶聚合会生成映射到父存储桶的文档集合。类型参数用于定义父索引。 例如,我们有一个品牌及其不同的模型,然后模型类型将有以下_parent字段 -

{
   "model" : {
      "_parent" : {
         "type" : "brand"
      }
   }
}

还有许多其他特殊的桶聚合,这在许多其他情况下是有用的,它们分别是 -

  • 日期直方图汇总/聚合
  • 日期范围汇总/聚合
  • 过滤聚合
  • 过滤器聚合
  • 地理距离聚合
  • GeoHash网格聚合
  • 全局汇总
  • 直方图聚合
  • IPv4范围聚合
  • 失踪聚合
  • 嵌套聚合
  • 范围聚合
  • 反向嵌套聚合
  • 采样器聚合
  • 重要条款聚合
  • 术语聚合

聚合元数据

可以通过使用元标记在请求时添加关于聚合的一些数据,并可以获得响应。 例如,

POST http://localhost:9200/school*/report/_search

请求正文

{
   "aggs" : {
      "min_fees" : { "avg" : { "field" : "fees" } ,
         "meta" :{
            "dsc" :"Lowest Fees"
         }
      }
   }
}

响应

{
   "aggregations":{"min_fees":{"meta":{"dsc":"Lowest Fees"}, "value":2180.0}}
}

Elasticsearch索引API


这些API负责管理索引的所有方面,如设置,别名,映射,索引模板。

创建索引

此API可用于创建索引。 当用户将JSON对象传递到任何索引时,可以自动创建索引,也可以在此之前创建索引。 要创建索引,只需要发送包含设置,映射和别名的发布请求,或者只发送一个没有正文的简单请求。 例如,

POST http://localhost:9200/colleges

响应

{"acknowledged":true}

或者,加上一些设置 -

POST http://localhost:9200/colleges

请求正文

{
   "settings" : {
      "index" : {
         "number_of_shards" : 5, "number_of_replicas" : 3
      }
   }
}

响应

{"acknowledged":true}

或使用映射 -

POST http://localhost:9200/colleges

请求正文

{
   "settings" : {
      "number_of_shards" : 3
   },

   "mappings" : {
      "type1" : {
         "_source" : { "enabled" : false }, "properties" : {
            "college_name" : { "type" : "string" }, "college type" : {"type":"string"}
         }
      }
   }
}

响应

{"acknowledged":true}

或者,用别名 -

POST http://localhost:9200/colleges

请求正文

{
   "aliases" : {
      "alias_1" : {}, "alias_2" : {
         "filter" : {
            "term" : {"user" : "manu" }
         },
         "routing" : "manu"
      }
   }
}

响应

{"acknowledged":true}

删除索引

此API可用来删除任何索引。只需要传递一个删除请求以及指定索引的URL。 例如,

DELETE http://localhost:9200/colleges

可以通过使用_all,*删除所有索引。

获取索引

这个API可以通过发送get请求到一个或多个索引来调用。这将返回有关索引的信息。

GET http://localhost:9200/schools

响应

{
   "schools":{
      "aliases":{}, "mappings":{
         "school":{
            "properties":{
               "city":{"type":"string"}, "description":{"type":"string"},
               "fees":{"type":"long"}, "location":{"type":"double"},
               "name":{"type":"string"}, "rating":{"type":"string"},
               "state":{"type":"string"}, "street":{"type":"string"},
               "tags":{"type":"string"}, "zip":{"type":"string"}
            }
         }
      },

      "settings":{
         "index":{
            "creation_date":"1454409831535", "number_of_shards":"5",
            "number_of_replicas":"1", "uuid":"iKdjTtXQSMCW4xZMhpsOVA",
            "version":{"created":"2010199"}
         }
      },
      "warmers":{}
   }
}

可以使用_all*来获取所有索引的信息。

测试索引存在

可以通过向该索引发送获取请求来确定索引的存在。如果HTTP响应为200,则存在; 如果是404,它不存在。

打开/关闭索引API

通过在post中添加_close_open来请求索引,可以很容易地关闭或打开一个或多个索引。 例如,
关闭索引-

POST http://localhost:9200/schools/_close

或打开索引-

POST http://localhost:9200/schools/_open

索引别名

此API有助于使用_aliases关键字向任何索引提供别名。 单个别名可以映射到多个别名,且别名不能与索引具有相同的名称。 例如,

POST http://localhost:9200/_aliases

请求正文

{
   "actions" : [
      { "add" : { "index" : "schools", "alias" : "schools_pri" } }
   ]
}

响应

{"acknowledged":true}

然后,

GET http://localhost:9200/schools_pri

响应

{"schools":{"aliases":{"schools_pri":{}},"}}

索引设置

可以通过在URL结尾处附加_settings关键字来获取索引设置。 例如,

GET http://localhost:9200/schools/_settings

响应

{
   "schools":{
      "settings":{
         "index":{
            "creation_date":"1454409831535", "number_of_shards":"5", 
            "number_of_replicas":"1", "uuid":"iKdjTtXQSMCW4xZMhpsOVA", 
            "version":{"created":"2010199"}
        }
      }
   }
}

分析

此API有助于分析文本并使用偏移值和数据类型发送令牌。 例如,

POST http://localhost:9200/_analyze

请求正文

{
   "analyzer" : "standard",
   "text" : "you are reading this at YIIBAI point"
}

响应

{
   "tokens":[
      {"token":"you", "start_offset":0, "end_offset":3, "type":"<ALPHANUM>", "position":0},
      {"token":"are", "start_offset":4, "end_offset":7, "type":"<ALPHANUM>", "position":1},
      {"token":"reading", "start_offset":8, "end_offset":15, "type":"<ALPHANUM>", "position":2},
      {"token":"this", "start_offset":16, "end_offset":20, "type":"<ALPHANUM>", "position":3},
      {"token":"at", "start_offset":21, "end_offset":23, "type":"<ALPHANUM>", "position":4},
      {"token":"tutorials", "start_offset":24, "end_offset":33, "type":"<ALPHANUM>", "position":5},
      {"token":"point", "start_offset":34, "end_offset":39, "type":"<ALPHANUM>", "position":6}
   ]
}

还可以使用任何索引分析文本,然后根据与该索引关联的分析器来分析文本。

索引模板

还可以创建具有映射的索引模板,这可以应用于新的索引。 例如,

POST http://localhost:9200/_template/template_a

响应

{
   "template" : "tu*", 
      "settings" : {
         "number_of_shards" : 3
   },

   "mappings" : {
      "chapter" : {
         "_source" : { "enabled" : false }
      }
   }
}

以“tu”开头的任何索引都将具有与模板相同的设置。

索引统计

此API可用于提取有关特定索引的统计信息。只需要发送一个带有索引URL_stats关键字的get请求。

GET http://localhost:9200/schools/_stats

响应

………………………………………………
{"_shards":{"total":10, "successful":5, "failed":0}, "_all":{"primaries":{"docs":{
   "count":3, "deleted":0}}}, "store":{"size_in_bytes":16653, "throttle_time_in_millis":0},
………………………………………………

刷新清除数据

此API用于从索引内存中清除数据,并将其迁移到索引存储,并清除内部事务日志。 例如,

GET http://localhost:9200/schools/_flush

响应

{"_shards":{"total":10, "successful":5, "failed":0}}

 刷新索引

默认情况下,刷新在Elasticsearch中一般按计划来执行,但可以使用_refresh显式刷新一个或多个索引。 例如,

GET http://localhost:9200/schools/_refresh

响应

{"_shards":{"total":10, "successful":5, "failed":0}}

Elasticsearch集群API


此API用于获取有关集群及其节点的信息,并对其进行更改。 对于调用此API,需要指定节点名称,地址或_local。 例如,

GET http://localhost:9200/_nodes/_local

或者

Get http://localhost:9200/_nodes/127.0.0.1

响应

... ...
{
   "cluster_name":"elasticsearch", "nodes":{
      "Vy3KxqcHQdm4cIM22U1ewA":{
         "name":"Red Guardian", "transport_address":"127.0.0.1:9300", 
         "host":"127.0.0.1", "ip":"127.0.0.1", "version":"2.1.1", 
         "build":"40e2c53", "http_address":"127.0.0.1:9200",
      }
   }
}
... ...

集群运行状况

此API用于通过追加health关键字来获取集群运行状况的状态。 例如,

GET http://localhost:9200/_cluster/health

响应

{
   "cluster_name":"elasticsearch", "status":"yellow", "timed_out":false,
   "number_of_nodes":1, "number_of_data_nodes":1, "active_primary_shards":23,
   "active_shards":23, "relocating_shards":0, "initializing_shards":0,
   "unassigned_shards":23, "delayed_unassigned_shards":0, "number_of_pending_tasks":0,
   "number_of_in_flight_fetch":0, "task_max_waiting_in_queue_millis":0,
   "active_shards_percent_as_number":50.0
}

集群状态

此API用于通过附加’state‘关键字URL来获取有关集群的状态信息。状态信息包含:版本,主节点,其他节点,路由表,元数据和块。 例如,

GET http://localhost:9200/_cluster/state 10. Elasticsearch — Cluster APIs

响应

{
   "cluster_name":"elasticsearch", "version":27, "state_uuid":"B3P7uHGKQUGsSsiX2rGYUQ",
   "master_node":"Vy3KxqcHQdm4cIM22U1ewA",

}

群集统计信息

此API有助于使用’stats‘关键字检索有关集群的统计信息。 此API返回碎片编号,存储大小,内存使用情况,节点数,角色,操作系统和文件系统。 例如,

GET http://localhost:9200/_cluster/stats

响应

{
   "timestamp":1454496710020, "cluster_name":"elasticsearch", "status":"yellow",
   "indices":{
      "count":5, "shards":{
         "total":23, "primaries":23, "replication":0.0,"
      }
   }
}

正在等待的群集任务

此API用于监视任何集群中的挂起任务。任务类似于创建索引,更新映射,分配碎片,故障碎片等。例如,

GET http://localhost:9200/_cluster/pending_tasks

集群重新路由

此API用于将分片从一个节点移动到另一个节点,或者用于取消任何分配或分配任何未分配的碎片。 例如,

POST http://localhost:9200/_cluster/reroute

请求正文

{
   "commands" : [ 
      {
         "move" :
         {
            "index" : "schools", "shard" : 2,
            "from_node" : "nodea", "to_node" : "nodeb"
         }
      },

      {
         "allocate" : {
            "index" : "test", "shard" : 1, "node" : "nodec"
         }
      }
   ]
}

群集更新设置

此API允许使用settings关键字更新群集的设置。有两种类型的设置 - persistent(在重新启动时应用)和transient(在完全群集重新启动后不会生存)。

节点统计

此API用于检索集群的一个节点的统计信息。节点状态与集群几乎相同。 例如,

GET http://localhost:9200/_nodes/stats

响应

{
   "cluster_name":"elasticsearch", "nodes":{
      "Vy3KxqcHQdm4cIM22U1ewA":{
         "timestamp":1454497097572, "name":"Red Guardian", 
         "transport_address":"127.0.0.1:9300", "host":"127.0.0.1", "ip":["127.0.0.1:9300",
      }
   }
}

节点hot_threads

此API可用于检索有关集群中每个节点上当前热线程的信息。 例如,

GET http://localhost:9200/_nodes/hot_threads

响应

{Red Guardian} {Vy3KxqcHQdm4cIM22U1ewA} {127.0.0.1}{127.0.0.1:9300}Hot threads at 
   2017-02-01T10:59:48.856Z, interval = 500ms, busiestThreads = 3, 
   ignoreIdleThreads = true:0.0% (0s out of 500ms) cpu usage by thread 'Attach Listener'
      unique snapshot
      unique snapshot

Elasticsearch查询DSL


Elasticsearch中,通过使用基于JSON的查询进行搜索。 查询由两个子句组成 -

  • 叶查询子句 - 这些子句是匹配,项或范围的,它们在特定字段中查找特定值。
  • 复合查询子句 - 这些查询是叶查询子句和其他复合查询的组合,用于提取所需的信息。

Elasticsearch支持大量查询。 查询从查询关键字开始,然后以JSON对象的形式在其中包含条件和过滤器。以下描述了不同类型的查询 -

匹配所有查询

这是最基本的查询; 它返回所有内容,并为每个对象的分数为1.0。 例如,

POST http://localhost:9200/schools*/_search

请求正文

{
   "query":{
      "match_all":{}
   }
}

响应

{
   "took":1, "timed_out":false, "_shards":{"total":10, "successful":10, "failed":0},
   "hits":{
      "total":5, "max_score":1.0, "hits":[
         {
            "_index":"schools", "_type":"school", "_id":"2", "_score":1.0,
            "_source":{
               "name":"Saint Paul School", "description":"ICSE Affiliation",
               "street":"Dawarka", "city":"Delhi", "state":"Delhi", 
               "zip":"110075", "location":[28.5733056, 77.0122136], "fees":5000, 
               "tags":["Good Faculty", "Great Sports"], "rating":"4.5"
            }
         },

         {
            "_index":"schools_gov", "_type":"school", "_id":"2", "_score":1.0,
            "_source":{
               "name":"Government School", "description":"State Board Affiliation",
               "street":"Hinjewadi", "city":"Pune", "state":"MH", "zip":"411057",
               "location":[18.599752, 73.6821995], "fees":500, "tags":["Great Sports"],
               "rating":"4"
            }
         },

         {
            "_index":"schools", "_type":"school", "_id":"1", "_score":1.0,
            "_source":{
               "name":"Central School", "description":"CBSE Affiliation",
               "street":"Nagan", "city":"paprola", "state":"HP", 
               "zip":"176115", "location":[31.8955385, 76.8380405], 
               "fees":2200, "tags":["Senior Secondary", "beautiful campus"], 
               "rating":"3.3"
            }
         },

         {
            "_index":"schools_gov", "_type":"school", "_id":"1", "_score":1.0,
            "_source":{
               "name":"Model School", "description":"CBSE Affiliation",
               "street":"silk city", "city":"Hyderabad", "state":"AP", 
               "zip":"500030", "location":[17.3903703, 78.4752129], "fees":700, 
               "tags":["Senior Secondary", "beautiful campus"], "rating":"3"
            }
         },

         {
            "_index":"schools", "_type":"school", "_id":"3", "_score":1.0,
            "_source":{
               "name":"Crescent School", "description":"State Board Affiliation",
               "street":"Tonk Road", "city":"Jaipur", "state":"RJ", "zip":"176114",
               "location":[26.8535922, 75.7923988], "fees":2500, 
               "tags":["Well equipped labs"], "rating":"4.5"
            }
         }
      ]
   }
}

全文查询

这些查询用于搜索整个文本,如章节或新闻文章。 此查询根据与特定索引或文档相关联的分析器一起工作。 在本节中,我们将讨论不同类型的全文查询。

匹配查询

此查询将文本或短语与一个或多个字段的值匹配。 例如,

POST http://localhost:9200/schools*/_search

请求正文

{
   "query":{
      "match" : {
         "city":"pune"
      }
   }
}

响应

{
   "took":1, "timed_out":false, "_shards":{"total":10, "successful":10, "failed":0},
   "hits":{
      "total":1, "max_score":0.30685282, "hits":[{
         "_index":"schools_gov", "_type":"school", "_id":"2", "_score":0.30685282, 
         "_source":{
            "name":"Government School", "description":"State Board Afiliation",
            "street":"Hinjewadi", "city":"Pune", "state":"MH", "zip":"411057",
            "location":[18.599752, 73.6821995], "fees":500, 
            "tags":["Great Sports"], "rating":"4"
         }
      }]
   }
}

multi_match查询

此查询将文本或短语与多个字段匹配。 例如,

POST http://localhost:9200/schools*/_search

请求正文

{
   "query":{
      "multi_match" : {
         "query": "hyderabad",
         "fields": [ "city", "state" ]
      }
   }
}

响应

{
   "took":16, "timed_out":false, "_shards":{"total":10, "successful":10, "failed":0},
   "hits":{
      "total":1, "max_score":0.09415865, "hits":[{
         "_index":"schools_gov", "_type":"school", "_id":"1", "_score":0.09415865,
         "_source":{
            "name":"Model School", " description":"CBSE Affiliation", 
            "street":"silk city", "city":"Hyderabad", "state":"AP", 
            "zip":"500030", "location":[17.3903703, 78.4752129], "fees":700, 
            "tags":["Senior Secondary", "beautiful campus"], "rating":"3"
         }
      }]
   }
}

查询字符串查询

此查询使用查询解析器和query_string关键字。 例如,

POST http://localhost:9200/schools/_search

请求正文

{
   "query":{
      "query_string":{
         "query":"good faculty"
      }
   }
}

响应

{
   "took":16, "timed_out":false, "_shards":{"total":10, "successful":10, "failed":0}, 
   "hits":{
      "total":1, "max_score":0.09492774, "hits":[{
         "_index":"schools", "_type":"school", "_id":"2", "_score":0.09492774, 
         "_source":{
            "name":"Saint Paul School", "description":"ICSE Affiliation",
            "street":"Dawarka", "city":"Delhi", "state":"Delhi",
            "zip":"110075", "location":[28.5733056, 77.0122136],
            "fees":5000, "tags":["Good Faculty", "Great Sports"],
            "rating":"4.5" 
         }
      }]
   }
}

期限等级查询

这些查询主要处理结构化数据,如数字,日期和枚举。 例如,

POST http://localhost:9200/schools/_search

请求正文

{
   "query":{
      "term":{"zip":"176115"}
   }
}

响应

{
   "took":1, "timed_out":false, "_shards":{"total":10, "successful":10, "failed":0},
   "hits":{
      "total":1, "max_score":0.30685282, "hits":[{
         "_index":"schools", "_type":"school", "_id":"1", "_score":0.30685282,
         "_source":{
            "name":"Central School", "description":"CBSE Affiliation",
            "street":"Nagan", "city":"paprola", "state":"HP", "zip":"176115",
            "location":[31.8955385, 76.8380405], "fees":2200, 
            "tags":["Senior Secondary", "beautiful campus"], "rating":"3.3"
         }
      }]
   }
}

范围查询

此查询用于查找值的范围之间的值的对象。 为此,需要使用类似 -

  • gte − 大于和等于
  • gt − 大于
  • lte − 小于和等于
  • lt − 小于

例如 -

POST http://localhost:9200/schools*/_search

请求正文

{
   "query":{
      "range":{
         "rating":{
            "gte":3.5
         }
      }
   }
}

响应

{
   "took":31, "timed_out":false, "_shards":{"total":10, "successful":10, "failed":0},
   "hits":{
      "total":3, "max_score":1.0, "hits":[
         {
            "_index":"schools", "_type":"school", "_id":"2", "_score":1.0,
            "_source":{
               "name":"Saint Paul School", "description":"ICSE Affiliation",
               "street":"Dawarka", "city":"Delhi", "state":"Delhi", 
               "zip":"110075", "location":[28.5733056, 77.0122136], "fees":5000, 
               "tags":["Good Faculty", "Great Sports"], "rating":"4.5"
            }
         }, 

         {
            "_index":"schools_gov", "_type":"school", "_id":"2", "_score":1.0, 
            "_source":{
               "name":"Government School", "description":"State Board Affiliation",
               "street":"Hinjewadi", "city":"Pune", "state":"MH", "zip":"411057",
               "location":[18.599752, 73.6821995] "fees":500, 
               "tags":["Great Sports"], "rating":"4"
            }
         },

         {
            "_index":"schools", "_type":"school", "_id":"3", "_score":1.0,
            "_source":{
               "name":"Crescent School", "description":"State Board Affiliation",
               "street":"Tonk Road", "city":"Jaipur", "state":"RJ", "zip":"176114", 
               "location":[26.8535922, 75.7923988], "fees":2500,
               "tags":["Well equipped labs"], "rating":"4.5"
            }
         }
      ]
   }
}

其他类型的期限级查询是 -

  • 存在的查询 - 如果某一个字段有非空值。
  • 缺失的查询 - 这与存在查询完全相反,此查询搜索没有特定字段的对象或有空值的字段。
  • 通配符或正则表达式查询 - 此查询使用正则表达式来查找对象中的模式。

类型查询 - 具有特定类型的文档。 例如,

POST http://localhost:9200/schools*/_search

请求正文

{
   "query":{
      "type" : {
         "value" : "school"
      }
   }
}

响应
存在于指定的索引中的所有学校的JSON对象。

复合查询

这些查询是通过使用如等,用于不同索引或具有函数调用等的布尔运算符彼此合并的不同查询的集合。例如,

POST http://localhost:9200/schools*/_search

请求正文

{
   "query":{
      "filtered":{
         "query":{
            "match":{
               "state":"UP"
            }
         },

         "filter":{
            "range":{
               "rating":{
                  "gte":4.0
               }
            }
         }
      }
   }
}

响应

{
   "took":16, "timed_out":false, "_shards":{"total":10, "successful":10, "failed":0},
   "hits":{"total":0, "max_score":null, "hits":[]}
}

连接查询

这些查询用于包含多个映射或文档的位置。 连接查询有两种类型 -

嵌套查询
这些查询处理嵌套映射(将在下一章阅读了解更多内容)。

has_child和has_parent查询

这些查询用于检索在查询中匹配的文档的子文档或父文档。 例如,

POST http://localhost:9200/tutorials/_search

请求正文

{
   "query":
   {
      "has_child" : {
         "type" : "article", "query" : {
            "match" : {
               "Text" : "This is article 1 of chapter 1"
            }
         }
      }
   }
}

响应

{
   "took":21, "timed_out":false, "_shards":{"total":5, "successful":5, "failed":0},
   "hits":{
      "total":1, "max_score":1.0, "hits":[{
         "_index":"tutorials", "_type":"chapter", "_id":"1", "_score":1.0,
         "_source":{
            "Text":"this is chapter one"
         }
      }]
   }
}

地理查询

这些查询处理地理位置和地理点。这些查询有助于查找任何位置附近的学校或任何其他地理对象。需要使用地理位置数据类型。 例如,

POST http://localhost:9200/schools*/_search

请求正文

{
   "query":{
      "filtered":{
         "filter":{
            "geo_distance":{
               "distance":"100km",
               "location":[32.052098, 76.649294]
            }
         }
      }
   }
}

响应

{
   "took":6, "timed_out":false, "_shards":{"total":10, "successful":10, "failed":0},
   "hits":{
      "total":2, "max_score":1.0, "hits":[
         {
            "_index":"schools", "_type":"school", "_id":"2", "_score":1.0,
            "_source":{
               "name":"Saint Paul School", "description":"ICSE Affiliation",
               "street":"Dawarka", "city":"Delhi", "state":"Delhi", "zip":"110075",
               "location":[28.5733056, 77.0122136], "fees":5000,
               "tags":["Good Faculty", "Great Sports"], "rating":"4.5"
            }
         },

         {
            "_index":"schools", "_type":"school", "_id":"1", "_score":1.0,
            "_source":{
               "name":"Central School", "description":"CBSE Affiliation",
               "street":"Nagan", "city":"paprola", "state":"HP", "zip":"176115",
               "location":[31.8955385, 76.8380405], "fees":2000,
               "tags":["Senior Secondary", "beautiful campus"], "rating":"3.5"
            }
         }
      ]
   }
}

注意 - 如果在执行上述示例时遇到异常,请将以下映射添加到索引。

{
   "mappings":{
      "school":{
         "_all":{
            "enabled":true
         },

         "properties":{
            "location":{
               "type":"geo_point"
            }
         }
      }
   }
}

Elasticsearch映射


映射是存储在索引中的文档的大纲。它定义数据类型,如geo_point或文档和规则中存在的字段的字符串和格式,以控制动态添加的字段的映射。 例如,

POST http://localhost:9200/bankaccountdetails

请求正文

{
   "mappings":{
      "report":{
         "_all":{
            "enabled":true
         },

         "properties":{
            "name":{ "type":"string"}, "date":{ "type":"date"},
            "balance":{ "type":"double"}, "liability":{ "type":"double"}
         }
      }
   }
}

响应

{"acknowledged":true}

字段数据类型
Elasticsearch支持文档中字段的多种不同数据类型。以下数据类型用于在Elasticsearch中存储字段 -

  • 核心数据类型 - 这些是几乎所有系统支持的基本数据类型,如整数,长整数,双精度,短整型,字节,双精度,浮点型,字符串,日期,布尔和二进制。
  • 复杂数据类型 - 这些数据类型是核心数据类型的组合。类似数组,JSON对象和嵌套数据类型。以下是嵌套数据类型的示例 -
POST http://localhost:9200/tabletennis/team/1

请求正文

{
   "group" : "players",
   "user" : [
      {
         "first" : "dave", "last" : "jones"
      },

      {
         "first" : "kevin", "last" : "morris"
      }
   ]
}

响应

{
   "_index":"tabletennis", "_type":"team", "_id":"1", "_version":1, 
   "_shards":{"total":2, "successful":1, "failed":0}, "created":true
}
  • 地理数据类型
    这些数据类型用于定义地理属性。 例如,geo_point用于定义经度和纬度,geo_shape用于定义不同的几何形状,如矩形。

  • 专用数据类型
    这些数据类型用于特殊目的,如IPv4(“ip”)接受IP地址,完成数据类型用于支持自动完成建议,token_count用于计算字符串中的令牌数量。

映射类型

每个索引都具有一个或多个映射类型,用于将索引的文档划分为逻辑组。 映射可以基于以下参数有些不同 -

  • 元字段
    这些字段提供有关映射和与其关联的其他对象的信息。 例如_index_type_id_source字段。

  • 字段
    不同的映射包含不同数量的字段和具有不同数据类型的字段。

动态映射

Elasticsearch为自动创建映射提供了一个用户友好的机制。用户可以将数据直接发布到任何未定义的映射,Elasticsearch将自动创建映射,这称为动态映射。 例如,

POST http://localhost:9200/accountdetails/tansferreport

请求正文

{
   "from_acc":"7056443341", "to_acc":"7032460534",
   "date":"11/1/2016", "amount":10000
}

响应

{
   "_index":"accountdetails", "_type":"tansferreport",
   "_id":"AVI3FeH0icjGpNBI4ake", "_version":1,
   "_shards":{"total":2, "successful":1, "failed":0},
   "created":true
}

映射参数

映射参数定义映射的结构,关于字段和关于存储的信息以及如何在搜索时分析映射的数据。 这些是以下映射参数 -

  • analyzer
  • boost
  • coerce
  • copy_to
  • doc_values
  • dynamic
  • enabled
  • fielddata
  • geohash
  • geohash_precision
  • geohash_prefix
  • format
  • ignore_above
  • ignore_malformed
  • include_in_all
  • index_options
  • lat_lon
  • index
  • fields
  • norms
  • null_value
  • position_increment_gap
  • properties
  • search_analyzer
  • similarity
  • store
  • term_vector

Elasticsearch分析


当在搜索操作期间处理查询时,任何索引中的内容由分析模块分析。该模块由分析器,分词器,分词器过滤器和字符过滤器组成。 如果没有定义分析器,则默认情况下注册内置的分析器,分词器,分词器过滤器和字符过滤器到分析模块。例如。

POST http://localhost:9200/pictures

请求正文

{
   "settings": {
      "analysis": {
         "analyzer": {
            "index_analyzer": {
               "tokenizer": "standard", "filter": [
                  "standard", "my_delimiter", "lowercase", "stop", 
                     "asciifolding", "porter_stem"
               ]
            },

            "search_analyzer": {
               "tokenizer": "standard", "filter": [
                  "standard", "lowercase", "stop", "asciifolding", "porter_stem"
               ]
            }
         },

         "filter": {
            "my_delimiter": {
               "type": "word_delimiter",
               "generate_word_parts": true,
               "catenate_words": true,
               "catenate_numbers": true,
               "catenate_all": true,
               "split_on_case_change": true,
               "preserve_original": true,
               "split_on_numerics": true,
               "stem_english_possessive": true
            }
         }
      }
   }
}

响应

{"acknowledged":true}

分析器

分析器由令牌器和可选的令牌过滤器组成。这些分析器在具有逻辑名的分析模块中注册,可以在映射定义或某些API中引用它们。有许多默认分析仪如下 -

编号分析器描述
1 标准分析器(标准) 为此分析仪设置停止字词和最大令牌长度。默认情况下,停用字词列表为空,最大标记长度(max_token_length)为255。
2 简单分析器(简单) 这个分析器由小写分词器组成。
3 空白分析器(空格) 这个分析器由空白分词器组成。
4 关键字分析器(关键字) 此分析器将整个流标记为单个令牌。 它可以用于邮政编码。
5 模式分析器(模式) 该分析器主要处理正则表达式。可以在此分析器中设置像小写字母,模式,标志,无用词的设置。
6 语言分析器 该分析器处理像印第安语,阿拉伯语,荷兰语等语言。
7 雪球分析器(雪球) 此分析仪使用标准分段器,带有标准滤波器,小写字母过滤器,停止过滤器和雪球过滤器。
8 停止分析器(停止) stopwordsstopwords_path可以配置。 默认情况下,停用词初始化为英语停用词,stopwords_path包含具有停用词的文本文件的路径。
9 自定义分析器(自定义) 此分析器用于创建带有可选令牌过滤器和字符过滤器的令牌化器的定制分析器。可以在此分析器中配置像tokenizerfilterchar_filterposition_increment_gap等设置。

令牌器/标记生成器

令牌器用于从Elasticsearch中的文本生成令牌。 通过考虑空白或其他标点符号,文本可以分解成令牌。 Elasticsearch有大量内置的分词器,可以在自定义分析器中使用。

编号标记生成器描述
1 标准标记生成器(标准) 这是建立在基于语法的标记生成器,以及max_token_length可以配置为这个标记生成器。
2 边缘NGram标记生成器(edgeNGram) 可以为此分词器设置如:min_grammax_gramtoken_chars的设置。
3 关键字标记生成器(关键字) 这将生成整个输入作为输出,可以为此设置buffer_size
4 字母标记生成器 这将捕获整个单词,直到遇到一个非字母字符。
5 小写标记生成器(小写) 这与标记生成器相同,但是在创建令牌之后,会将它们更改为小写。
6 NGram令牌器(nGram) 类似:min_gram(默认值为1),max_gram(默认值为2)和token_chars等设置可以为这个分词器。
7 空格标记符(空格) 这将根据空格分隔文本。
8 模式分词器(模式) 这使用正则表达式作为标记分隔符。可以为此分词器设置模式,标志和组设置。
9 UAX电子邮件URL令牌(uax_url_email) 这使用正则表达式作为标记分隔符。 可以为此分词器设置模式,标志和组设置。
10 这与标准分词器工作方式相同,但它将电子邮件和URL作为单个标记。  
11 路径层次化标记分隔符(path_hierarchy) 此标记器生成输入目录路径中存在的所有可能的路径。可用于此分词器的设置是分隔符(默认为/),replacementbuffer_size(默认为1024),reverse(默认为false)和skip(默认为0)。
12 经典分词器(经典) 这在基于令牌的语法基础上工作。可以为此分词器设置:max_token_length
13 泰语分词器(泰语) 此分词器用于泰语,并使用内置的泰语分词算法。

令牌过滤器

令牌过滤器从令牌化器接收输入,然后这些过滤器可以修改,删除或添加输入的文本。 Elasticsearch提供了大量内置的令牌过滤器。它们中的大多数已经在前面的部分中解释。

字符过滤器

这些过滤器在分词器之前处理文本。 字符过滤器查找特殊字符或html标签或指定的模式,然后删除或更改为适当的词,如’&‘到和,删除html标记标记。 这里是同义词在synonym.txt中指定的分析器的示例 -

{
   "settings":{
      "index":{
         "analysis":{
            "analyzer":{
               "synonym":{
                  "tokenizer":"whitespace", "filter":["synonym"]
               }
            },

            "filter":{
               "synonym":{
                  "type":"synonym", "synonyms_path":"synonym.txt", "ignore_case":"true"
               }
            }
         }
      }
   }
}

Elasticsearch模块


Elasticsearch由多个模块组成,这些模块负责其功能。 这些模块有以下两种类型的设置 -

  • 静态设置 - 在启动Elasticsearch之前,需要在配置文件(elasticsearch.yml)中配置这些设置。需要更新集群中的所有关注节点以反映这些设置的更改。

  • 动态设置 - 这些设置可以在实时Elasticsearch上设置。

我们将在本章的以下部分讨论Elasticsearch中的每个模块。

集群级路由和碎片分配

集群级别设置决定将碎片分配给不同节点,以及将碎片重新分配给平衡集群。这些是以下设置来控制碎片分配 -

集群级碎片分配-

  • cluster.routing.allocation.enable 可能的值及说明 -

    • all - 此默认值允许为所有种类的碎片分配碎片。
    • primaries - 这允许只为主碎片分配碎片。
    • new_primaries- 这允许只为新索引的主碎片分配碎片。
    • none- 这不允许任何碎片分配。
  • cluster.routing.allocation.node_concurrent_recoveries - 一个数字值(默认为2 ),它限制了并发碎片恢复的数量。

  • cluster.routing.allocation.node_initial_primaries_recoveries - 一个数字值(默认为 4 ),它限制了并行初始初级恢复的数量。

  • cluster.routing.allocation.same_shard.host - 布尔值(默认为false), 它限制了同一物理节点中同一碎片的多个副本的分配。

  • indices.recovery.concurrent _streams - 一个数字值(默认为3 ),它控制在从对等体碎片恢复碎片时每个节点的开放网络流的数量。

  • indices.recovery.concurrent_small_file_streams - 一个数字值(默认为2 ),这控制了在碎片恢复时对于小于5mb的小文件的每个节点的开放流的数量。

  • cluster.routing.rebalance.enable可能的值及说明 -

    • all - 此默认值允许平衡所有种类的碎片。
    • primaries- 这允许只对主碎片进行碎片平衡。
    • replicas - 这允许只对副本碎片进行碎片平衡。
    • none - 这不允许任何类型的碎片平衡。
  • cluster.routing.allocation.allow_rebalance 可能的值及说明 -

    • always - 此默认值始终允许重新平衡。
    • indices_primaries _active - 这允许在分配集群中的所有主碎片时进行重新平衡。
    • Indices_all_active - 这允许在分配所有主碎片和副本碎片时重新平衡。
  • cluster.routing.allocation.cluster _concurrent_rebalance - 一个数字值(默认为2 ), 这限制了集群中的并发碎片平衡数。

  • cluster.routing.allocation.balance.shard - 一个浮点数值(默认为0.45f ),这定义了在每个节点上分配的碎片的权重因子。

  • cluster.routing.allocation.balance.index - 一个浮点数值(默认为0.55f ),这定义了在特定节点上分配的每个索引的碎片数量的比率。

  • cluster.routing.allocation.balance.threshold - 一个浮点数值(默认为1.0f ),这定义了在特定节点上分配的每个索引的碎片数量的比率。

  • cluster.routing.allocation .balance.threshold - 非负浮点值(默认为1.0f)这是应该执行的操作的最小优化值。

基于磁盘的碎片分配

设置可能的值描述
cluster.routing.allocation.disk.threshold_enabled 布尔值(默认为true) 这启用和禁用磁盘分配决策程序。
cluster.routing.allocation.disk.watermark.low 字符串值(默认为85%) 这表示磁盘的最大使用; 此后,无法将其他碎片分配给该磁盘。
cluster.routing.allocation.disk.watermark.high 字符串值(默认为90%) 这表示分配时的最大使用量; 如果在分配时达到这一点,Elasticsearch将把该碎片分配给另一个磁盘。
cluster.info.update.interval 字符串值(默认30s) 这是磁盘用法,检查两个时间之间的间隔。
cluster.routing.allocation.disk.include_relocations 布尔值(默认为true) 这决定在计算磁盘使用率时是否考虑当前分配的分片。
     
   

发现

此模块帮助集群发现和维护其中的所有节点的状态。在从集群添加或删除节点时集群的状态发生更改。集群名称设置用于在不同集群之间创建逻辑差异。有一些模块,可以帮助您使用云供应商提供的API -

  • Azure发现
  • EC2发现
  • Google计算引擎发现
  • Zen发现

网关

此模块在整个群集重新启动时维护群集状态和分片数据。以下是此模块的静态设置 -

设置可能的值描述
gateway.expected_nodes 数值(默认为0) 预期在群集中用于恢复本地碎片的节点数。
gateway.expected_master_nodes 数值(默认为0) 在开始恢复之前预期在群集中的主节点数。
gateway.expected_data_nodes 数值(默认为0) 开始恢复之前群集中预期的数据节点数。
gateway.recover_after_time 字符串值(默认为5m) 这用于指定恢复进程将等待启动的时间,而不考虑在集群中加入的节点数。1. gateway.recover_after_nodes 2. gateway.recover_after_master_nodes 3. gateway.recover_after_data_nodes

HTTP

此模块管理HTTP客户端和Elasticsearch API之间的通信。可以通过将http.enabled的值更改为false来禁用此模块。 以下是控制此模块的设置(在elasticsearch.yml中配置)

编号设置描述
1 http.port 访问Elasticsearch的端口,范围为9200-9300
2 http.publish_port 此端口用于HTTP客户端,并且在防火墙的情况下也很有用。
3 http.bind_host http服务的主机地址。
4 http.publish_host http客户端的主机地址。
5 http.max_content_length 这是http请求中内容的最大值。其默认值为100mb
6 http.max_initial_line_length 这是URL的最大值,其默认值为4kb
7 http.max_header_size 这是最大http报头大小,其默认值为8kb
8 http.compression 这启用或禁用对压缩的支持,其默认值为false
9 http.pipelinig 这将启用或禁用HTTP通道线。
10 http.pipelining.max_events 这会限制在关闭HTTP请求之前排队的事件数。

索引

此模块维护对每个索引全局设置的设置。以下设置主要与内存使用有关 -

断路器

这用于防止操作引起OutOfMemroyError。 该设置主要限制JVM堆大小。 例如,indices.breaker.total.limit设置,JVM堆的默认为70%

Fielddata缓存

这主要用于在字段上聚合时。建议分配它足够的内存。 可以使用indices.fielddata.cache.size设置控制用于字段数据高速缓存的内存量。

节点查询缓存

此内存用于缓存查询结果。此缓存使用最近最少使用(LRU)逐出策略。 Indices.queries.cahce.size设置控制此缓存的内存大小。

索引缓冲区

此缓冲区将新创建的文档存储在索引中,并在缓冲区已满时将其刷新。设置为indices.memory.index_buffer_size控制为此缓冲区分配的堆的大小。

Shard请求缓存

此缓存用于存储每个分片的本地搜索数据。缓存可以在创建索引期间启用,也可以通过发送URL参数来禁用。

Disable cache - ?request_cache = true
Enable cache "index.requests.cache.enable": true

索引恢复

它在恢复过程中控制资源。以下是一些设置 -

设置默认值
indices.recovery.concurrent_streams 3
indices.recovery.concurrent_small_file_streams 2
indices.recovery.file_chunk_size 512kb
indices.recovery.translog_ops 1000
indices.recovery.translog_size 512kb
indices.recovery.compress true
indices.recovery.max_bytes_per_sec 40mb

TTL间隔

生存时间(TTL)间隔定义文档的时间,之后文档将被删除。 以下是控制此过程的动态设置 -

设置默认值
indices.ttl.interval 60
indices.ttl.bulk_size 1000

节点

每个节点有一个选项是否是数据节点。可以通过更改node.data设置更改此属性。将值设置为false将定义该节点不是数据节点。

Elasticsearch测试


Elasticsearch提供了一个jar文件,可以将其添加到任何Java IDE,并可用于测试与Elasticsearch相关的代码。 可以使用Elasticsearch提供的框架执行一系列测试 -

  • 单元测试
  • 集成测试
  • 随机测试

要开始测试,需要向程序添加Elasticsearch测试依赖关系。您可以使用maven来实现此目的,并且可在pom.xml中添加以下内容。

<dependency>
   <groupId>org.elasticsearch</groupId>
   <artifactId>elasticsearch</artifactId>
   <version>2.1.0</version>
</dependency>

EsSetup初始化用来启动和停止Elasticsearch节点,并创建索引。

EsSetup esSetup = new EsSetup();

esSetup.execute()函数与createIndex用于创建索引,需要指定设置,类型和数据。

单元测试

单元测试是通过使用JUnit和Elasticsearch测试框架来进行的。可以使用Elasticsearch类创建节点和索引,并且在测试方法中可以用来执行测试。ESTestCaseESTokenStreamTestCase类用于此测试。

集成测试

集成测试在集群中使用多个节点。 ESIntegTestCase类用于这种类型的测试。 有多种方法使得准备测试用例的工作更容易。

编号方法描述
1 refresh() 刷新群集中的所有索引
2 ensureGreen() 确保绿色健康集群状态
3 ensureYellow() 确保黄色的健康群集状态
4 createIndex(name) 使用传递给此方法的名称创建索引
5 flush() 刷新群集中的所有索引
6 flushAndRefresh() 执行 flush() 和 refresh()
7 indexExists(name) 验证指定索引是否存在
8 clusterService() 返回集群服务java类
9 cluster() 返回测试集群类

测试集群方法

编号方法描述
1 ensureAtLeastNumNodes(n) 确保群集中最小节点数量大于或等于指定数量。
2 ensureAtMostNumNodes(n) 确保群集中最大节点数小于或等于指定数。
3 stopRandomNode() 停止集群中的随机节点
4 stopCurrentMasterNode() 停止主节点
5 stopRandomNonMaster() 停止集群中的随机节点(不是主节点)
6 buildNode() 创建一个新节点
7 startNode(settings) 启动一个新节点
8 nodeSettings() 覆盖此方法以更改(更新)节点设置

访问客户端

客户端用于访问集群中的不同节点并执行某些操作。ESIntegTestCase.client()方法用于获取随机客户端。Elasticsearch还提供了其他方法来访问客户端,这些方法可以使用ESIntegTestCase.internalCluster()方法访问。

编号方法描述
1 iterator() 这用于访问所有可用的客户端。
2 masterClient() 返回一个正在与主节点通信的客户端。
3 nonMasterClient() 返回一个不与主节点通信的客户端。
4 clientNodeClient() 将返回当前在客户端节点上的客户端。

随机测试

随机测试是用于使用所有可能的数据测试用户的代码,以便将来不会出现任何类型的数据失败。 随机数据是进行此测试的最佳选择。

生成随机数据

在这个测试中,Random类由RandomizedTest提供的实例实例化,并提供了许多方法来获取不同类型的数据。

方法返回值
getRandom() 随机类的实例
randomBoolean() 随机布尔值
randomByte() 随机字节值
randomShort() 随机短整型值
randomInt() 随机整型值
randomLong() 随机长整型值
randomFloat() 随机浮点值
randomDouble() 随机双精度浮点值
randomLocale() 随机区域设置
randomTimeZone() 随机时区
randomFrom() 数组中的随机元素

断言

ElasticsearchAssertionsElasticsearchGeoAssertions类包含断言,用于在测试时执行一些常见检查。 例如,

SearchResponse seearchResponse = client().prepareSearch();
assertHitCount(searchResponse, 6);
assertFirstHit(searchResponse, hasId("6"));
assertSearchHits(searchResponse, "1", "2", "3", "4",”5”,”6”);

 

posted @ 2022-04-20 17:17  hanease  阅读(81)  评论(0编辑  收藏  举报