栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

elasticsearch怎么用(elasticsearch实战与原理解析pdf)

elasticsearch怎么用(elasticsearch实战与原理解析pdf)

目录

1. Elasticsearch的数据类型 2

1.1. 理解index、type、文档 2

1.2. 为了加深理解index、type、文档概念,下面列出了常用的ES URL概览 2

1.3. 向ES中存储数据 3

1.4. ES数据格式 3

1.5. ES数据类型映射 4

1.6. ES实际是如何存储复杂对象的? 8

2. ES查询 9

2.1. ES简单查询例子 9

2.2. 查询方式的分类 10

2.2.1. 概念解释: 10

2.2.2. Query和Filter(bool查询)的区别 10

2.3. ES Query查询语法 10

2.4. Bool(filter)查询语法 12

2.4.1. BooleanQuery查询例子 12

2.4.2. BooleanQuery查询语法 14

2.4.3. BooleanQuery例子解析 14

3. 结束语 

    Elasticsearch的数据类型

1.1理解index、type、文档

站在使用者的角度考虑的话,index和type仅仅是url路径中的一个值。站在开发者的角度讲,index就相当于表,type就相当于表的一个字段,定义了这些数据的类型。文档则通常为JSON格式表示的数据。

补充说明:ES 7.X版本为什么已经移除了Type的概念?

1)ES中同一个index中不同type是存储在同一个索引中的(lucene的索引文件),因此不同type中相同名字的字段的定义(mapping)必须一致;

2)外在同一个index中存储含有不同字段的文档会导致稀疏数据并干扰Lucene高效压缩文档的能力,降低es效率

   1.2为了加深理解index、type、文档概念,下面列出了常用的ES URL

大类

小类

url规则

请求方式

Body体

索引操作

创建索引

http://ip:port/{索引名}

Put

在请求体里面传入设置或类型映射(可选,可设置主分片数、副本数、分词器、字段类型等)

{"settings": {},"mappings": {}}

删除索引

http://ip:port/{索引名}

Delete

查询索引列表

http://ip:port/_cat/indices?v

文档管理

添加

http://ip:port/{索引}/{type}/{_id}

Put

json形式的文档

修改

http://ip:port/{索引}/{type}/{_id}

Post

json形式的文档

删除

http://ip:port/{索引}/{type}/{_id}

Delete

根据_id取文档

http://ip:port/{索引}/{type}/{_id}

Get

使用批处理_bulk

http://ip:port/{索引}/_bulk

PutPost

固定格式的消息体或文件

查询数据

查询

http://ip:port/{索引}/{type}/_search

Post

json形式的查询语句{"query":{查询体}}

查询全部match_all

http://ip:port/{索引}/_search

Post

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

其他查询

查询的url规则都一样,不同的是body体,后面会详细介绍。

Post

1.3 通过http请求,向ES中存储数据

向ES中存储数据时,传入的json如下:

PUT my-index-000001/_doc/1

{

    "age": 79,

    "name": {

        "full": "John Smith",

        "first": "John",

        "last": "Smith"

    },

    "address": "35 Chauncey Street, Grazierville, Missouri",

    "createdAt": "2021-03-16",

    "updatedAt": "22021-03-16 01:16:30"

}

通过向ES中存储数据,大家思考下ES拿到数据之后,如何处理?

字段的识别数据类型转换根据字段类型进行分词处理并索引。

1.4 ES数据格式

ES的数据格式基本有如下几种类型:

字符串: string数值: double、long等布尔型: BooleanObject:对应上面的user、user.name为Object类型数组日期类型:ES日期类型可以有3种表示方式:1)格式化的date字符串,例如"2018-01-01"或者"2018-01-01 12:00:00" 。 2)一个long型的数字,代表从1970年1月1号0点到现在的毫秒数。 3)一个integer型的数字,代表从1970年1月1号0点到现在的秒数。

ES复杂数据类型:

binary: double、long等keyword: Boolean等等

思考:

1)json包含哪些数据类型?ES包含哪些数据类型?ES会如何存储JSON数据呢?

备注:在es内部,date被转为UTC,并被存储为一个长整型数字,代表从1970年1月1号0点到现在的毫秒数;date类型字段上的查询会在内部被转为对long型值的范围查询,查询的结果类型是字符串。

1.5 ES数据类型映射

上述JSON存储到ES后,会映射为如下格式:

{
    "account": {
        "mappings": {
            "_doc": {
                "properties": {
                    "address": {"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},
                    "age": {"type":"long"},
                    "createdAt": {"type":"date"},
                    "name": {"properties":{"first":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"full":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}},"last":{"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}}},
                    "updatedAt": {"type":"text","fields":{"keyword":{"type":"keyword","ignore_above":256}}}
                }
            }
        }
    }
}

1.6 ES实际是如何存储复杂对象的?

实际上,针对上面类型映射,在ES底层实际映射为简单的健值对,如下:

{

"age": 79,

"name.full":"John Smith",

"name.first":"John",

"name.last":"Smith",

"address": "35 Chauncey Street, Grazierville, Missouri",

"createdAt": "2021-03-16",

"updatedAt": "22021-03-16 01:16:30"

}

对于对象数组:

{

    "followers": [

        { "age": 35, "name": "Mary White"},

        { "age": 26, "name": "Alex Jones"},

        { "age": 19, "name": "Lisa Smith"}

    ]

}

会变成

{

    "followers.age":    [19, 26, 35],

    "followers.name":   [alex, jones, lisa, smith, mary, white]

}

{age: 35} 和 {name: Mary White} 之间的相关性已经丢失了,所以在查询操作的时候,我们不能得到一个准确的答案:“是否有一个26岁名字叫 Alex Jones 的追随者?”。

2. ES查询介绍

介绍了ES的存储数据类型,下面给大家介绍下ES的查询,下面先看一个查询的例子。

2.1 ES简单查询例子

post /account/_doc/_search?pretty

{

    "query": {

        "match": {

            "address":"Gallatin Place"

        }

    },

    "from": 0,

    "size": 10

}

上面仅仅是一个最简单的查询,实际上ES可支持很多类型的查询操作,下面先介绍下ES的查询分哪两类。

2.1查询方式的分类

ES查询方式分为query、filter(bool查询)两类。这两种查询有什么区别呢?下面先看下两者个概念解释。

2.2.1 概念解释:

Query:在查询上下文中,查询子句回答“此文档与此查询子句匹配程度如何?”的问题。除了决定文档是否匹配外,查询子句还会在 _score 元字段中计算相关性分数。

Filter:在过滤器上下文中,查询子句回答“此文档是否与此查询子句匹配?”的问题。答案是简单的 Yes 或 No —— 不计算分数。Filter主要对文档进行过滤,例如 这个时间戳是否在 2015 年到 2016 年的范围内? 状态字段是否设置为“已发布”?

2.2.2 Query和Filter(bool查询)的区别

1)使用方面:

filter仅仅只是按照搜索条件过滤出需要的数据而已,不计算任何相关度分数,对相关度没有任何影响;

query会去计算每个document相对于搜索条件的相关度,并按照相关度进行排序。

一般来说,如果你是在进行搜索,需要将最匹配搜索条件的数据先返回,那么用query;如果你只是要根据一些条件筛选出一部分数据,不关注其排序,那么用filter。

2)性能方面:

filter不计算相关度分数,不按照相关度分数进行排序,同时还有内置的自动cache最常使用filter的数据;

query相反,要计算相关度分数,按照分数进行排序,而且无法cache结果。

2.3 ES Query查询语法

ES的查询根据是否进行分词,分为“Full text query”和“Term-level query”。

Full text query:对文字进行分词之后,再进行查询。例如查询“hello world”的时候,会通过空格分为“hello”和“world”两个词之后,再进行查询。

Term-level query:查询不会再对query内容进行analysis分词处理,直接将query当做一个单词处理。例如:例如查询“hello world”的时候,仅匹配“hello world”。

大类

小类

解释

例子

分词匹配检索

match_all

match

对内容分词之后,查询ES进行匹配

{"query": {"match": {"address":"Gallatin Place"}}}

query_string

分词后进行匹配,支持AND、OR等DSL语言。不指定fields,默认会在当前index所有可以查询的字段中进行查询。

{"query": {"query_string": {"query":"Gallatin AND Place","fields":["address"]}}}

match_phrase

查询短语

{"query": {"match_phrase": {"address":{"query":"33 Street","slop":  1}}}}

combined_fields

查询多个字段

{"query": {"combined_fields" : {"query":"database systems","fields":[ "title", "abstract", "body"],"operator":   "and"}}}

精确匹配查询

exists

{"query": {"exists": {"field": "user"}}

Fuzzy

模糊匹配

{"query": {"fuzzy": {"address": {"value": "roa"}}}}

Ids

查询id

{"query": {"ids" : {"values" : ["1", "4", "100"]}}}

prefix前缀查询

前缀查询

{"query": {"prefix": {"name": {"value": "sc"}}}}

range

range范围查询

{"query": {"range": {"age": {"gte": 10, "lte": 20, "boost": 2.0}}}}

term查询(不进行分词)

适合对价格、商品ID、用户名查询

{"query": {"term": {"address": {"value": "street", "boost": 1.0} }}}

wildcard通配符查询

通配符查询

{

  "query": {

    "wildcard": {

        "company": "inv*re"

    }

  }

}

通过上面的例子可以看出,ES查询的基本语法为如下格式的JSON:

{

    "query": {

        "查询操作类型(match、query_string等)": {

            

        }

    }

}

2.4 Bool(filter)查询语法

bool查询映射到Lucene的BooleanQuery查询,用来查询与boolean条件匹配的文档;它由一个或者多个boolean子句组成。下面看下BooleanQuery查询例子。

2.4.1 BooleanQuery查询例子

POST _search

{

  "query": {

    "bool" : {

      "must" : {

        "term" : { "user.id" : "kimchy" }

      },

      "filter": {

        "term" : { "tags" : "production" }

      },

      "must_not" : {

        "range" : {

          "age" : { "gte" : 10, "lte" : 20 }

        }

      },

      "should" : [

        { "term" : { "tags" : "env1" } },

        { "term" : { "tags" : "deployed" } }

      ],

      "minimum_should_match" : 1,

      "boost" : 1.0

    }

  }

}

2.4.2 BooleanQuery查询语法

通过上面的例子可以看出,bool元素包含must、must_not、filter、should四个操作符,操作符中又可以包含查询条件(可以包含match、term、range等等查询语法,又可包含bool查询子句)。

Boolean查询条件操作符

解释

上述例子解析

must

文档必须匹配must中的条件,并计算分值。

must里的条件必须全部为true才能返回。

查询user.id匹配kimchy的记录。

filter

必须匹配,但对返回的score无影响,只是根据过滤标准来排除或包含文档。(不计分)

返回所有文档的tags字段包含production内容的记录。

should

should则是包含的条件里有一个条件为true就返回,如果满足这些语句中的任意语句,将增加 _score的分值。可以通过设置minimum_should_match的值(数值或者百分比),来设置需要满足should中的几个条件。

*当bool查询包含should,不包含must或者filter的时候,minimum_should_match的默认值为1,否则为0。

文档的tags字段为env1或者deployed

must_not

文档 必须不 匹配这些条件才能被包含进来。

年龄不在10-20岁之间

2.4.3 BooleanQuery例子解析

1)下面的查询用于查找 title 字段匹配 how to make millions 并且不被标识为 spam 的文档。那些被标识为 starred 或在2014之后的文档,将比另外那些文档拥有更高的排名,如果 两者 都满足,那么它排名将更高。

{"query": {

     "bool": {

        "must":     { "match": { "title": "how to make millions" }},

        "must_not": { "match": { "tag":   "spam" }},

        "should": [

            { "match": { "tag": "starred" }},

            { "range": { "date": { "gte": "2014-01-01" }}}

        ]

 }}}

2)带filter的查询

{"query": {

    "bool": {

        "must":     { "match": { "title": "how to make millions" }},

        "must_not": { "match": { "tag":   "spam" }},

        "should": [

            { "match": { "tag": "starred" }}

        ],

        "filter": {

          "range": { "date": { "gte": "2014-01-01" }} 

        }

}}}

range 查询移到 filter 语句中,date的内容将不再影响文档的score分值

3)bool嵌套

{"query": {

    "bool": {

        "must":     { "match": { "title": "how to make millions" }},

        "must_not": { "match": { "tag":   "spam" }},

        "should": [

            { "match": { "tag": "starred" }}

        ],

        "filter": {

          "bool": { 

              "must": [

                  { "range": { "date": { "gte": "2014-01-01" }}},

                  { "range": { "price": { "lte": 29.99 }}}

              ],

              "must_not": [

                  { "term": { "category": "ebooks" }}

              ]

}}}}}

结束语

上面为面向入门者写的简单的ES入门手册,掌握了上述内容之后,应付正常工作和使用已经绰绰有余了。

需要了解更多ES内容的同学可以移步官网(Quick start | Elasticsearch Guide [8.1] | Elastic),对于英文阅读困难的同学可访问中文网站(基础入门 | Elasticsearch: 权威指南 | Elastic),但中文网站的内容比较老旧,是基于 Elasticsearch 2.x 版本编写。

如果对您有用,麻烦点赞!

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/771583.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号