美文网首页
ElasticSearch in Action

ElasticSearch in Action

作者: 奉先 | 来源:发表于2019-11-03 09:17 被阅读0次

    1. 安装ElatsticSearch环境:

    首先,安装JRE,然后安装和启动ElasticSearch(使用Homebrew安装):

    $ brew install elasticsearch
    $ elasticsearch                   #启动es
    $ brew list elasticsearch     #查看es安装路径
    

    ES的默认的9300端口用于节点间通信,适用于Java API,而端口9200默认用户HTTP通信。浏览器访问localhost的9300端口(es默认监听从9200端口进入的HTTP请求),http://localhost:9200/ 有如下回应


    Elasticsearch kopf 是一个ES监控和发送请求的图形化工具,Github地址: https://github.com/lmenezes/elasticsearch-kopf

    重要:官网使用手册https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

    2. ES的基本操作和环境配置:

    ES最重要的两个操作分别是索引数据和搜索数据,其中搜索数据更加重要。

    2.1 索引数据

    我随便新建一个索引

    3.索引、更新和删除数据

    3.1 使用映射来定义文档

    从数据的逻辑划分来看 ,可以认为索引是数据库,而类型是数据库中的表,文档是数据行。但是从物理上,同一个 Elasticsearch 索引中的所有文挡,无论何种类型,都是存储在属于相同分片的同一组文件中。当多个类型中出现同样的字段名称时,两个同名的字段应该有同样的设置。类型包含了映射中每个字段的定义,映射包括了该类型的文档中可能出现的所有字段。
    下面代码创建一个索引(索引名crud_index_test,类型名:poi,文档名:B0FFG77NR6):

    curl -H 'Content-Type: application/json' -XPUT 'localhost:9200/crud_index_test/poi/B0FFG77NR6' -d'{
     "name": "南京格瑞特金属幕墙板制造有限公司(东北门)",
     "pc_type": 2,
     "create_time": "2019-11-08",
     "enable": true,
     "name_quanpin": [
         "nan'jing'jia'chang'mei'dian'zi'shang'wu",
         "nanjingjiachangmeidianzishangwuyouxiangongsi"
     ]
    }'
    

    因为ES会在创建文档时,自动为我们生成映射文件。下面代码可以查看某个索引的映射,使用_mapping,其中参数?pretty可以结构化输出(JSON格式)我们的返回结果:

    curl -XGET 'localhost:9200/crud_index_test/_mapping/poi?pretty'
    
    
    {
      "crud_index_test" : {
        "mappings" : {
          "poi" : {
            "properties" : {
              "create_time" : {
                "type" : "date"
              },
              "enable" : {
                "type" : "boolean"
              },
              "name" : {
                "type" : "text",
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              },
              "name_quanpin" : {
                "type" : "text",
                "fields" : {
                  "keyword" : {
                    "type" : "keyword",
                    "ignore_above" : 256
                  }
                }
              },
              "pc_type" : {
                "type" : "long"
              }
            }
          }
        }
      }
    }
    
    

    如果在现有的基础上再设置一个映射,Elasticsearch会将两者进行合并。例如,下边请求直接修改poi类型的映射,该操作会在原有映射基础上增加一个string类型的poi_address字段。

    curl -H 'Content-Type: application/json' -XPUT 'localhost:9200/crud_index_test/_mapping/poi' -d'
    {
        "poi": {
            "properties": {
                "poi_address": {
                    "type": "text"
                }
            }
        }
    }'
    

    日期的format,可以在官网参考:www.elastic.co/guide/reference/mapping/date-format/
    修改映射时,需要注意如果修改原有的类型,那么会失败,除非把所有索引的数据删除后,重新索引。

    3.2 数据类型、数组、多字段

    Elasticsearch中一个字段可以是核心类型,也可以是一个从核心类型派生的复杂类型(如数组)。核心类型包括: 字符串、数值、日期、布尔几种类型。

    1.在字段mapping中,有一个字段级的index,其取值有几种选择:
    true/false:是否被索引。
    2.对于日期类型,我们可以指定其格式,例如yyyy-MM-dd等。

    curl -H 'Content-Type: application/json' -XPUT 'localhost:9200/crud_index_test/_mapping/poi' -d'
    {
        "poi": {
            "properties": {
                "parent_id": {
                    "type": "text",
                    "index":true
                },
                "end_date": {
                    "type": "date",
                    "format":"yyyy-MM-dd"
                }
            }
        }
    }'
    

    3.在mapping中,如何定义一个数组呢,其实跟core type无异,数组是字符串类型,直接设置为text类型即可。

    3.3 预定义字段

    官网参考
    常见常用的一些预定义字段包括: _source在索引文档的时候,存储原始的JSON文档。_id、 _type 和_index唯一识别文档。使用_size来索引原始JSON内容的大小。_routing控制文档路由到哪些分片。
    预定义的字段总是以下划线开头。我们无需构建,这些字段es为文档添加的元数据

    1._source 字段按照原有格式来存储原有的文档。
    在我们查询某个文档(需要索引/类型/文档id三级)时,返回结果就会有_source字段,_source字段按照原有格式来存储原有的文档。 同时,也可以通过stored_fields查具体字段,例如:

    curl -XGET 'localhost:9200/crud_index_test/poi/B0FFG77NR6?pretty'
    curl -XGET 'localhost:9200/crud_index_test/poi/B0FFG77NR6?pretty&stored_fields=name,pc_type'
    
    1. _id,_type,_index
      分别指的文档id,类型和索引。
    curl -XGET 'localhost:9200/_search?q=_index:crud_index_test&pretty'
    

    3.4 更新文档

    文档的更新包括检索文档、处理文档、并重新索引文档,直至先前的文档被覆盖。
    修改部分字段,使用_update发送POST请求,来修改原来的文档,也可以通过upsert选项,类似sql中upsert语句。

    curl -H 'Content-Type: application/json'  -XPOST 'localhost:9200/crud_index_test/poi/B0FFG77NR6/_update?pretty' -d '{"doc" : { "pc_type":1}}'
    curl -H 'Content-Type: application/json'  -XPOST 'localhost:9200/crud_index_test/poi/B001907CB1/_update?pretty' -d '{
        "doc":{
            "pc_type":1
        },
        "upsert":{
            "name":"新宁五金建材",
            "address":"江宁区 将军大道99-36号",
            "pc_type":2
        }
    }'
    

    在更新过程中,需要注意冲突,可以使用版本来实现并发控制。

    删除单个文档或者一组丈档。删除整个索引。关闭索引。其中,关闭的索引不允许读取或者写入操作,数据也不会加载到内存。但是索引还是保留在磁盘上。
    为了完成删除,需要向其URL发送HTTP DELETE请求。同时,也可以删除查询匹配的那些文档。

    curl -XDELETE 'localhost:9200/crud_index_test/poi/B001907CB1/?pretty'
    curl -XPOST 'localhost:9200/crud_index_test/_close?pretty'
    curl -XPOST 'localhost:9200/crud_index_test/_open?pretty'
    

    4.搜索数据

    (20191111)

    4.1 搜索请求的结构

    Elasticsearch的搜索是基于JSON文档或者是基于URL的请求,REST搜索请求使用_search的REST端点,通过_search来指定搜索的范围,例如,下面两个分别针对整个集群和crud_index_test索引来搜索:
    curl -XGET 'localhost:9200/_search' -d ''
    curl -XGET 'localhost:9200/crud_index_test/_search' -d ''

    限制好请求范围后,就需要配置搜索请求中最为重要的模块,基本包括:query、size、from、size、sort等,详细可参考官网文档。在搜索时,可以使用基于URL请求主体(JSON)的请求。其中,请求主体的方式更加灵活和强大。

    下面语句使用了几个参数,分别介绍下它们的含义,from,size:返回索引结果集合中从第from个开始的size个索引。sort是按照某个字段来对结果索引集合来排序,_source是限制返回的结果的字段。

    curl -XGET 'localhost:9200/crud_index_test/_search?pretty&from=1&size=5&sort=create_time:desc&_source=name,create_time,enable'
    

    当执行更多高级搜索的时候,采用基于请求主体的搜索会使得你拥有更多的灵活性和选择性。用请求主体方式,重新生成上边的URL请求:

    curl -H 'Content-Type: application/json' -XGET 'localhost:9200/crud_index_test/_search?pretty' -d '      
    {
        "query":{
            "match_all":{
    
            }
        },
        "from":0,
        "size":5,
        "sort":[
            {
                "create_time":"desc"
            }
        ],
        "_source":[
            "name",
            "create_time",
            "enable"
        ]
    }
    '
    

    简单介绍下,搜索返回结果一些关键key的意思。took:查询所用毫秒数。timed_out:表名是否有分片超时(也就是是否只返回了部分结果)。_shards:此次查询的分片使用情况,一共访问多少分片其中成功、忽略、失败的数量。hits:命中关键词元素中的命中文档数组。_source:原始的JSON文档。

    4.2 查询和过滤器DSL

    1. match和term混合查询:
      搜索的过滤器只是为“文档是否匹配这个查询”,返回简单的“是”或“否”的答案。过滤器可以比普通的查询更快而且还可以被缓存(不计算得分)。下面是一个过滤查询,包括查询和过滤器模块。filter部分用来筛选文档,不影响match部分文档得分。
    curl -H 'Content-Type: application/json' -XGET 'localhost:9200/crud_index_test/_search?pretty' -d '
    {
        "query":{
            "bool":{
                "must":[
                    {
                        "match":{
                            "name":"牧奇"
                        }
                    }
                ],
                "filter":[
                    {
                        "term":{
                            "create_time":"2019-11-10"
                        }
                    }
                ]
            }
        }
    }'
    
    1. query_string查询:
      query_string使用具有严格语法的解析器,根据提供的查询字符串(AND 和 OR等来组合查询)返回文档。默认情况下,query string查询将会搜索_all字段。但是可以使用default_field来指定默认的查询字段(如果在URL中没指定的话)。query_string查询的一个显著缺点是它实在是太强大了,可以写出很复杂的逻辑,但是如果用户输入了格式错误的查询,他们将得到返回的异常。
    curl -H 'Content-Type: application/json' -XGET 'localhost:9200/crud_index_test/_search?pretty' -d '
    {
        "query":{
            "query_string":{
                "query" : "(牧奇) OR (格瑞特)",
                "default_field" : "name"
            }
        }
    }'
    
    1. term查询和terms查询:
      term既可以作为查询,也可以作为过滤器。对于term查询来讲,被搜索的关键词是没有经过分析的,文档中的同条必须要精确匹配才能作为结果返回,这一点是与match的主要区别。
      和term查询相似,还可以使用term过滤器来限制结果文挡,使其包含特定的词条,不过无须计算得分(参考第1部分)。
      和term查询类似,terms查询(注意这里多一个s)可以搜索某个文档字段中的多个词条。
    curl -H 'Content-Type: application/json' -XGET 'localhost:9200/crud_index_test/_search?pretty' -d '
    {
        "query":{
            "term":{
                "name_quanpin" : "mengbaotongzhuang"
            }
        }
    }'
    
    curl -H 'Content-Type: application/json' -XGET 'localhost:9200/crud_index_test/_search?pretty' -d '
    {
        "query":{
            "terms":{
                "name_quanpin" : ["mengbaotongzhuang","nanjingnkpifuguanlimeijiameijiegongzuoshi"]
            }
        }
    }'
    

    4.3 match查询

    match查询可以有多种行为方式。最常见的是布尔(boolean)和词组(phrase)。默认情况下,match查询使用布尔行为和OR操作符。例如,"萌宝 格瑞特"会搜索命中了萌宝或者格瑞特的文档。使用"operator":"and"修改为了并且的关系。

    curl -H 'Content-Type: application/json' -XGET 'localhost:9200/crud_index_test/_search?pretty' -d '
    {
        "query":{
            "match":{
                "name" : "萌宝 格瑞特"
            }
        }
    }'
    
    curl -H 'Content-Type: application/json' -XGET 'localhost:9200/crud_index_test/_search?pretty' -d '
    {
        "query":{
            "match":{
                "name":{
                    "query":"萌宝 格瑞特",
                    "operator":"and"
                }
            }
        }
    }'
    

    第二个重要行为是作为 phrase 查询,每个单词的位置之间可以留有余地。这种余地称作slop,用于表示词组中多个分词之间的距离。使用match_phrase来查询。
    phrase_prefix查询是和词组中最后一个词条进行前缀匹配。
    multi_match查询和match查询很像,但是,多字段匹配允许你搜索多个字段中的值。对多个字段应用同一个搜索词。

    4.4 组合查询或复合查询

    bool查询允许你在单独的查询中组合任意数量的查询,指定的查询子句表明哪些部分是必须(must)匹配、应该(should)匹配或者是不能(must not)匹配上 Elasticsearch索引里的数据。
    1.must匹配,只有匹配上这些查询的结果才会被返回。
    2.should匹配,只有匹配上指定数量子句的文档才会被返回 。
    3.如果没有指定must匹配的子句,文档至少要匹配一个should子句才能返回。
    4.must not子句会使得匹配其的文档被移出结果集合。

    5. 分析数据

    5.1 Elasticsearch分析

    分析(analysis)是在文档被发送并加入倒排索引之前,Elasticsearch在其主体上进行的操作。

    相关文章

      网友评论

          本文标题:ElasticSearch in Action

          本文链接:https://www.haomeiwen.com/subject/bnjkbctx.html