欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

1.ElasticSearch简单了解

程序员文章站 2022-06-13 22:59:41
...

一个 Elasticsearch 集群可以 包含多个 索引 ,相应的每个索引可以包含多个 类型 。 这些不同的类型存储着多个 文档 ,每个文档又有 多个 属性 。

一个 索引 类似于传统关系数据库中的一个 数据库 ,是一个存储关系型文档的地方,类型有些类似于表

路径包含了三部分的信息:  索引(_index) + 类型(_type) + ID(_id) 

/_search
在所有的索引中搜索所有的类型
/gb/_search
在 gb 索引中搜索所有的类型
/gb,us/_search
在 gb 和 us 索引中搜索所有的文档
/g*,u*/_search
在任何以 g 或者 u 开头的索引中搜索所有的类型
/gb/user/_search
在 gb 索引中搜索 user 类型
/gb,us/user,tweet/_search
在 gb 和 us 索引中搜索 user 和 tweet 类型
/_all/user,tweet/_search
在所有的索引中搜索 user 和 tweet 类型
 
分页:
size 显示应该返回的结果数量,默认是 10
from 显示应该跳过的初始结果数量,默认是 0

如果每页展示 5 条结果,可以用下面方式请求得到 1 到 3 页的结果:
GET /_search?size=5
GET /_search?size=5&from=5
GET /_search?size=5&from=10
 

 

CURL 

// CURL VERB
curl -X<VERB> '<PROTOCOL>://<HOST>:<PORT>/<PATH>?<QUERY_STRING>' -d '<BODY>'
curl -Xget 'http://localhost:9200//megacorp/employee/_search' -d '{"query" : {"bool": {"must": {"match" : { "last_name" : "smith" }},"filter": {"range" : {"age" : { "gt" : 30 } }}}}}'

安装head

sudo elasticsearch/bin/plugin install mobz/elasticsearch-head

卸载head

elasticsearch/bin/plugin remove head

 

 

GET  +  索引(_index)/类型(_type)/ID(_id)  [?pretty] [?_source=key1,key2] [/_source] [?timeout=10ms] [?size=5&from=5]:执行查询;

pretty       将会调用 Elasticsearch 的 pretty-print 功能,该功能 使得 JSON 响应体更加可读;

_source     字段现在包含的只是我们请求的那些字段;只想得到 _source 字段,不需要任何元数据,使用 /_source;

timeout 设定超时时间;

size             显示应该返回的结果数量,默认是 10

from            显示应该跳过的初始结果数量,默认是 0

 

PUT +  索引(_index)/类型(_type)/ID(_id) [?op_type=create] [/_create] [?version=1&version_type=external]  + JSON请求体(JSON 文档):执行插入或修改。

返回值:                                     _version是对该索引数据执行了几次修改,created:false代表是修改。

op_type和_create功能相同:    只执行创建请求,即路径不存在的时候才执行索引请求,如果创建新文档的请求成功执行,Elasticsearch 会返回元数据和一个 201 Created 的 HTTP 响应码,如果已存在,返回409 Conflict 响应码;

version:                                   乐观锁,当版本符合时才进行修改。version_type=external时Elasticsearch 不是检查当前 _version 和请求中指定的版本号是否相同, 而是检查当前 _version 是否 小于 指定的版本号。version应该小于long。

 

POST +  索引(_index)/类型(_type) +  JSON请求体(JSON 文档):POST创建文档不输入ID,而是自动生成ID,保障是新增插入。

POST +  索引(_index)/类型(_type)/ID(_id) /_update +  JSON请求体(JSON 文档):当使用_update时对象被合并到一起,覆盖现有的字段,增加新的字段。

POST +  索引(_index)/类型(_type) /_validate/query?explain : 验证查询

 

DELETE  + 路径 :执行删除,成功返回一个 200 ok 的 HTTP 响应码,

 

 

 

映射和分析

映射, 就像数据库中的 schema ,是文档和域直接的关系,

查看映射

 

GET 索引(_index)/_mapping/类型(_type) 获取文档结构
Elasticsearch 支持 如下简单域类型:

 

字符串: string
整数 : byte, short, integer, long
浮点数: float, double
布尔型: boolean
日期: date
 

 

索引一个包含新域的文档--之前未曾出现-- Elasticsearch 会使用 动态映射 ,通过JSON中基本数据类型,尝试猜测域类型,使用如下规则

自定义域映射编辑

允许执行下面的操作:

1.全文字符串域和精确值字符串域的区别

2.使用特定语言分析器

3.优化域以适应部分匹配

4.指定自定义数据格式

 

域Type

域最重要的属性是 type 。对于不是 string 的域,你一般只需要设置 type,string 域映射的两个最重要 属性是 index 和 analyzer。

 

JSON type 域 type
字符串: foo bar string
布尔型: true / false boolean
整数: 123 byte
short
integer
long
浮点数: 123.45 float
double
字符串,有效日期: 2014-09-15 date

 

 

index 

index 属性控制怎样索引字符串。它可以是下面三个值:

analyzed  首先分析字符串,然后索引它。换句话说,以全文索引这个域。string 域 index 属性默认是 analyzed

not_analyzed  索引这个域,所以它能够被搜索,但索引的是精确值。不会对它进行分析。

no  不索引这个域。这个域不会被搜索到。

其他简单类型(例如 long , double , date 等)也接受 index 参数,但有意义的值只有 no 和 not_analyzed , 因为它们永远不会被分析

 

analyzed 

对于 analyzed 字符串域,用 analyzer 属性指定在搜索和索引时使用的分析器。默认, Elasticsearch 使用 standard 分析器, 但你可以指定一个内置的分析器替代它,例如 whitespace 、 simple 和 english :

 

 

其他mapping设置

 _source 

元数据: 

1.搜索结果包括了整个可用的文档——不需要额外的从另一个的数据仓库来取文档。

2.如果没有 _source 字段,部分 update 请求不会生效。

3.当你的映射改变时,你需要重新索引你的数据,有了_source字段你可以直接从Elasticsearch这样做,而不必从另一个(通常是速度更慢的)数据仓库取回你的所有文档。

4.当你不需要看到整个文档时,单个字段可以从 _source 字段提取和通过 get 或者 search 请求返回。

调试查询语句更加简单,因为你可以直接看到每个文档包括什么,而不是从一列id猜测它们的内容

可以禁用元数据

"_source": {
    "enabled":  false
}

 

_all

_all 字段:一个把其它字段值 当作一个大字符串来索引的特殊字段。 query_string 查询子句(搜索 ?q=john )在没有指定字段时默认使用 _all 字段

禁用

"my_type": {
    "_all": { "enabled": false }
}

或者通过 include_in_all 设置来逐个控制字段是否要包含在 _all 字段中,默认值是 true`。比如下例中title包含在_all内

 

PUT /my_index/my_type/_mapping
{
    "my_type": {
        "include_in_all": false,
        "properties": {
            "title": {
                "type":           "string",
                "include_in_all": true
            },
            ...
        }
    }
}
 _all 字段仅仅是一个 经过分词的 string 字段。它使用默认分词器来分析它的值,不管这个值原本所在字段指定的分词器。就像所有 string 字段,你可以配置 _all 字段使用的分词器

 

 

PUT /my_index/my_type/_mapping
{
    "my_type": {
        "_all": { "analyzer": "whitespace" }
    }
}

 

dynamic

当 Elasticsearch 遇到文档中以前 未遇到的字段,它用 dynamic mapping 来确定字段的数据类型并自动把新的字段添加到类型映射

true    动态添加新的字段--缺省

false   忽略新的字段

strict  如果遇到新字段抛出异常

dynamic设置可以适用在根对象上或者object类型的任意字段上。你应该默认地将dynamic设置为strict,但是为某个特定的内部对象启用它

PUT /my_index
{
    "mappings": {
        "my_type": {
            "dynamic":      "strict", 
            "properties": {
                "title":  { "type": "string"},
                "stash":  {
                    "type":     "object",
                    "dynamic":  true 
                }
            }
        }
    }
}

 

 

更新映射

删除索引

DELETE /gb

 

创建索引

PUT /gb 
{
  "mappings": {
    "tweet" : {
      "properties" : {
        "tweet" : {
          "type" :    "string",
          "analyzer": "english"
        },
        "date" : {
          "type" :   "date"
        },
        "name" : {
          "type" :   "string"
        },
        "user_id" : {
          "type" :   "long"
        }
      }
    }
  }
}

 

添加索引域

tweet 映射增加一个新的名为 tag 的 not_analyzed 的文本域

PUT /gb/_mapping/tweet
{
  "properties" : {
    "tag" : {
      "type" :    "string",
      "index":    "not_analyzed"
    }
  }
}

 

 

 

查询(elasticsearch-head 需要用POST执行复杂查询)

GET /索引名称/类型名称/_search   搜索所有,返回结果包括了所有文档,放在数组 hits 中

GET /索引名称/类型名称/_search[?q=key:value][?q=+key1:value1+key2:value2]   查询字符串 (_query-string_) 搜索,即key中包含value的文档,https://www.elastic.co/guide/cn/elasticsearch/guide/current/search-lite.html待深入,基本只有一个参数能成功

 

结果

hits ,它 包含 total 字段来表示匹配到的文档总数,并且一个 hits 数组包含所查询结果的前十个文档。

在 hits 数组中每个结果包含文档的 _index 、 _type 、 _id ,加上 _source 字段。这意味着我们可以直接从返回的搜索结果中使用整个文档。这不像其他的搜索引擎,仅仅返回文档的ID,需要你单独去获取文档。

每个结果还有一个 _score ,它衡量了文档与查询的匹配程度。默认情况下,首先返回最相关的文档结果,就是说,返回的文档是按照 _score 降序排列的。在这个例子中,我们没有指定任何查询,故所有的文档具有相同的相关性,因此对所有的结果而言 1 是中性的 _score 。

max_score 值是与查询所匹配文档的 _score 的最大值

 

took 值告诉我们执行整个搜索请求耗费了多少毫秒。

 

_shards 部分 告诉我们在查询中参与分片的总数,以及这些分片成功了多少个失败了多少个。

 

使用查询表达式搜索

GET  +  路径 + JSON请求体(JSON 文档)

{
    "query" : {
        "match" : {
            "key" : "value"
        }
    }
    "_source": [ "title", "created" ]
}

match 匹配查询 match_phrase 模糊匹配

高亮 highlight  {"fields" : {"about" : {}}}

 

更复杂的搜索

GET /megacorp/employee/_search  或者 POST /megacorp/employee/_search

{
    "query" : {
        "bool": {
            "must": {
                "match" : {
                    "key1" : "value1" 
                }
            },
            "filter": {
                "range" : {
                    "key2" : { "gt" : intValue2 } 
                }
            }
        }
    }
}

 intValue2是int类型,没有前后双引号

过滤器 filter支持结构化查询,比如范围查询 range

 

 

 

分析

聚合(aggregations),允许我们基于数据生成一些精细的分析结果。聚合与 SQL 中的 GROUP BY 类似但更强大。

 


集群健康

GET /_cluster/health

 

检查文档是否存在

curl -I -XHEAD http://localhost:9200/website/blog/123

 

如果文档存在, Elasticsearch 将返回一个 200 ok 的状态码:

HTTP/1.1 200 OK

Content-Type: text/plain; charset=UTF-8

Content-Length: 0

 

若文档不存在, Elasticsearch 将返回一个 404 Not Found 的状态码:

curl -I -XHEAD http://localhost:9200/website/blog/124

HTTP/1.1 404 Not Found

Content-Type: text/plain; charset=UTF-8

Content-Length: 0

 

使用脚本部分更新文档编辑

脚本可以在 update API中用来改变 _source 的字段内容, 它在更新脚本中称为 ctx._source 。 例如,我们可以使用脚本来增加博客文章中 views 的数量:

POST /website/blog/1/_update

{

   "script" : "ctx._source.views+=1"

}

 

取回多个文档,将多个请求合并成一个,避免单独处理每个请求花费的网络延时和开销。

mget API 要求有一个 docs 数组作为参数,每个 元素包含需要检索文档的元数据, 包括 _index 、 _type 和 _id 。如果你想检索一个或者多个特定的字段,那么你可以通过 _source 参数来指定这些字段的名字:

GET /_mget

{

   "docs" : [

      {

         "_index" : "website",

         "_type" :  "blog",

         "_id" :    2

      },

      {

         "_index" : "website",

         "_type" :  "pageviews",

         "_id" :    1,

         "_source": "views"

      }

   ]

}

如果想检索的数据都在相同的 _index 中(甚至相同的 _type 中),则可以在 URL 中指定默认的 /_index 或者默认的 /_index/_type 

GET /website/blog/_mget

{

   "docs" : [

      { "_id" : 2 },

      { "_type" : "pageviews", "_id" :   1 }

   ]

}

如果所有文档的 _index 和 _type 都是相同的,你可以只传一个 ids 数组,而不是整个 docs 数组:

GET /website/blog/_mget

{

   "ids" : [ "2", "1" ]

}

该响应体也包含一个 docs 数组 , 对于每一个在请求中指定的文档,这个数组中都包含有一个对应的响应,且顺序与请求中的顺序相同。

 

其他批量操作 bulk API

{ action: { metadata }}\n

{ request body        }\n

{ action: { metadata }}\n

{ request body        }\n

...

它通过换行符(\n)连接到一起。注意两个要点:

每行一定要以换行符(\n)结尾, 包括最后一行 。这些换行符被用作一个标记,可以有效分隔行。

这些行不能包含未转义的换行符,因为他们将会对解析造成干扰。这意味着这个 JSON 不 能使用 pretty 参数打印。