Elasticsearch的介绍及使用

1,993 阅读18分钟

Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户,能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据。

Elasticsearch是分布式的,这意味着索引可以被分成分片,每个分片可以有0个或多个副本。每个节点托管一个或多个分片,并充当协调器将操作委托给正确的分片。再平衡和路由是自动完成的。相关数据通常存储在同一个索引中,该索引由一个或多个主分片和零个或多个复制分片组成。一旦创建了索引,就不能更改主分片的数量。

Elasticsearch 是一个实时的分布式搜索分析引擎,它被用作全文检索、结构化搜索、分析以及这三个功能的组合,它是面向文档 的,意味着它存储整个对象或 文档。Elasticsearch 不仅存储文档,而且 索引每个文档的内容使之可以被检索。在 Elasticsearch 中,你 对文档进行索引、检索、排序和过滤--而不是对行列数据。

Elasticsearch 有2.x、5.x、6.x 三个大版本

Elasticsearch与Solr的比较

  • 二者安装都很简单;

  • Solr 利用 Zookeeper 进行分布式管理,而 Elasticsearch 自身带有分布式协调管理功能;

  • Solr 支持更多格式的数据,而 Elasticsearch 仅支持json文件格式;

  • Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,高级功能多有第三方插件提供;

  • Solr 在传统的搜索应用中表现好于 Elasticsearch,但在处理实时搜索应用时效率明显低于 Elasticsearch。

  • 搜索引擎从Solr转到Elasticsearch以后的平均查询速度有了50倍的提升

倒排索引

倒排索引(英语:Inverted index),也常被称为反向索引、置入档案或反向档案,是一种索引方法,被用来存储在全文搜索下某个单词在一个文档或者一组文档中的存储位置的映射。它是文档检索系统中最常用的数据结构。

假设我们有两个文档,每个文档的 content 域包含如下内容:

  1. The quick brown fox jumped over the , lazy+ dog

  2. Quick brown foxes leap over lazy dogs in summer

反向索引:

Term      Doc_1  Doc_2
-------------------------
Quick   |       |  X
The     |   X   |
brown   |   X   |  X
dog     |   X   |
dogs    |       |  X
fox     |   X   |
foxes   |       |  X
in      |       |  X
jumped  |   X   |
lazy    |   X   |  X
leap    |       |  X
over    |   X   |  X
quick   |   X   |
summer  |       |  X
the     |   X   |
------------------------

如果我们想搜索 quick brown ,我们只需要查找包含每个词条的文档:

Term      Doc_1  Doc_2
-------------------------
brown   |   X   |  X
quick   |   X   |
------------------------
Total   |   2   |  1

两个文档都匹配,但是第一个文档比第二个匹配度更高。如果我们使用仅计算匹配词条数量的简单相似性算法,那么,我们可以说,对于我们查询的相关性来讲,第一个文档比第二个文档更佳。

分析

上面不太合理的地方:

  • Quickquick 以独立的词条(token)出现,然而用户可能认为它们是相同的词。

  • foxfoxes 非常相似, 就像 dogdogs ;他们有相同的词根。

  • jumpedleap, 尽管没有相同的词根,但他们的意思很相近。他们是同义词。

进行标准化

  • Quick 可以小写化为 quick

  • foxes 可以词干提取--变为词根的格式-- 为 fox 。类似的, dogs 可以为提取为 dog

  • jumpedleap 是同义词,可以索引为相同的单词 jump

标准化的反向索引:

Term      Doc_1  Doc_2
-------------------------
brown   |   X   |  X
dog     |   X   |  X
fox     |   X   |  X
in      |       |  X
jump    |   X   |  X
lazy    |   X   |  X
over    |   X   |  X
quick   |   X   |  X
summer  |       |  X
the     |   X   |  X
------------------------

对于查询的字符串必须与词条(token)进行相同的标准化处理,才能保证搜索的正确性。

分词和标准化的过程称为 分析(analysis) :

  • 首先,将一块文本分成适合于倒排索引的独立的词条 -> 分词

  • 之后,将这些词条统一化为标准格式以提高它们的“可搜索性” -> 标准化

 分析工作是由分析器 (analyzer)完成的.

  • 字符过滤器

    首先,字符串按顺序通过每个字符过滤器,它们的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML,或者将 & 转化成 and

  • 分词器

    其次,字符串被分词器分为单个的词条。一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条。

  • Token 过滤器 (词条过滤器)

    最后,词条按顺序通过每个token 过滤器。这个过程可能会改变词条(例如,小写化 Quick ),删除词条(例如, 像 aandthe 等无用词),或者增加词条(例如,像 jumpleap 这种同义词)。

相关性排序

默认情况下,搜索结果是按照 相关性 进行倒序排序的——最相关的文档排在最前。

相关性可以用相关性评分表示,评分越高,相关性越高。

评分的计算方式取决于查询类型 不同的查询语句用于不同的目的: fuzzy 查询(模糊查询)会计算与关键词的拼写相似程度,terms 查询(词组查询)会计算 找到的内容与关键词组成部分匹配的百分比,但是通常我们说的 相关性 是我们用来计算全文本字段的值相对于全文本检索词相似程度的算法。

Elasticsearch 的相似度算法 被定义为检索词频率/反向文档频率,TF/IDF,包括以下内容:

  • 检索词频率

    检索词在该字段出现的频率?出现频率越高,相关性也越高。 字段中出现过 5 次要比只出现过 1 次的相关性高。

  • 反向文档频率

    每个检索词在索引中出现的频率?频率越高,相关性越低。检索词出现在多数文档中会比出现在少数文档中的权重更低。

  • 字段长度准则

    字段的长度是多少?长度越长,相关性越低。 检索词出现在一个短的 title 要比同样的词出现在一个长的 content 字段权重更大。

概念

存储数据到 Elasticsearch 的行为叫做索引(indexing).

关于数据的概念

Relational DB -> Databases 数据库 -> Tables 表 -> Rows 行 -> Columns 列
Elasticsearch -> Indices 索引库 -> Types 类型 -> Documents 文档 -> Fields 字段/属性

一个 Elasticsearch 集群可以 包含多个索引(indices 数据库),相应的每个索引可以包含多个

类型(type 表) 。 这些不同的类型存储着多个文档(document 数据行) ,每个文档又有 多个属性(field 列)。

Elasticsearch 集群(cluster)

Elasticsearch 尽可能地屏蔽了分布式系统的复杂性。这里列举了一些在后台自动执行的操作:

  • 分配文档到不同的容器 或分片中,文档可以储存在一个或多个节点中

  • 按集群节点来均衡分配这些分片,从而对索引和搜索过程进行负载均衡

  • 复制每个分片以支持数据冗余,从而防止硬件故障导致的数据丢失

  • 将集群中任一节点的请求路由到存有相关数据的节点

  • 集群扩容时无缝整合新节点,重新分配分片以便从离群节点恢复

节点(node)

一个运行中的 Elasticsearch 实例称为一个 节点,而集群是由一个或者多个拥有相同 cluster.name 配置的节点组成, 它们共同承担数据和负载的压力。当有节点加入集群中或者从集群中移除节点时,集群将会重新平均分布所有的数据。

当一个节点被选举成为 主 节点(master)时, 它将负责管理集群范围内的所有变更,例如增加、删除索引,或者增加、删除节点等。 而主节点并不需要涉及到文档级别的变更和搜索等操作,所以当集群只拥有一个主节点的情况下,即使流量的增加它也不会成为瓶颈。 任何节点都可以成为主节点。我们的示例集群就只有一个节点,所以它同时也成为了主节点。

作为用户,我们可以将请求发送到 集群中的任何节点 ,包括主节点。 每个节点都知道任意文档所处的位置,并且能够将我们的请求直接转发到存储我们所需文档的节点。 无论我们将请求发送到哪个节点,它都能负责从各个包含我们所需文档的节点收集回数据,并将最终结果返回給客户端。 Elasticsearch 对这一切的管理都是透明的。

分片(shard)

一个分片是一个底层的工作单元,它仅保存了 全部数据中的一部分。索引实际上是指向一个或者多个物理分片的逻辑命名空间。

文档被存储和索引到分片内,但是应用程序是直接与索引而不是与分片进行交互。

Elasticsearch 是利用分片将数据分发到集群内各处的。分片是数据的容器,文档保存在分片内,分片又被分配到集群内的各个节点里。 当你的集群规模扩大或者缩小时, Elasticsearch 会自动的在各节点中迁移分片,使得数据仍然均匀分布在集群里。

主分片(primary shard)

索引内任意一个文档都归属于一个主分片,所以主分片的数目决定着索引能够保存的最大数据量。

复制分片(副分片 replica shard)

一个副本分片只是一个主分片的拷贝。 副本分片作为硬件故障时保护数据不丢失的冗余备份,并为搜索和返回文档等读操作提供服务。

在索引建立的时候就已经确定了主分片数,但是副本分片数可以随时修改.

初始设置索引的分片方法

PUT /blogs
{
   "settings" : {
      "number_of_shards" : 3,
      "number_of_replicas" : 1
   }
}
  • number_of_shards

    每个索引的主分片数,默认值是 5 。这个配置在索引创建后不能修改。

  • number_of_replicas

    每个主分片的副本数,默认值是 1 。对于活动的索引库,这个配置可以随时修改。

    修改复制分片数目的方法

    PUT /blogs/_settings
    {
       "number_of_replicas" : 2
    }

    查看集群健康状态

    GET /_cluster/health
    
    {
       "cluster_name":          "elasticsearch",
       "status":                "green", 
       "timed_out":             false,
       "number_of_nodes":       1,
       "number_of_data_nodes":  1,
       "active_primary_shards": 0,
       "active_shards":         0,
       "relocating_shards":     0,
       "initializing_shards":   0,
       "unassigned_shards":     0
    }

    status 字段指示着当前集群在总体上是否工作正常。它的三种颜色含义如下:

    • green

      所有的主分片和副本分片都正常运行。

    • yellow

      所有的主分片都正常运行,但不是所有的副本分片都正常运行。

    • red

      有主分片没能正常运行。

    IK中文分析器

    github.com/medcl/elast…

    默认的elasticsearch是不支持中文的,可以选择下载一个版本,这里是5.6的。将elasticsearch-analysis-ik-5.6.16.zip 上传到Linux中。

    scp elasticsearch-analysis-ik-5.6.16.zip 用户名@服务器地址:~/

    安装

    sudo /usr/share/elasticsearch/bin/elasticsearch-plugin install file://zip文件的绝对路径

    安装成功后需要重启一下:

    sudo systemctl restart elasticsearch
    测试分析器
    curl -X GET 127.0.0.1:9200/_analyze?pretty -d '
    {
      "analyzer": "standard",
      "text": "我是&中国人"
    }'
    
    curl -X GET 127.0.0.1:9200/_analyze?pretty -d '
    {
      "analyzer": "ik_max_word", 
      "text": "我是&中国人"
    }'

索引与类型

索引

查看索引

curl 127.0.0.1:9200/_cat/indices

请求curl 127.0.0.1:9200/_cat可获取用于查询的名称

创建索引

索引可以在添加文档数据时,通过动态映射的方式自动生成索引与类型。

索引也可以手动创建,通过手动创建,可以控制主分片数目、分析器和类型映射。

PUT /my_index
{
    "settings": { ... any settings ... },
    "mappings": {
        "type_one": { ... any mappings ... },
        "type_two": { ... any mappings ... },
        ...
    }
}

注: 在Elasticsearch 5.x版本中,设置分片与设置索引的类型字段需要分两次设置完成。

删除索引

用以下的请求来 删除索引:

DELETE /my_index

你也可以这样删除多个索引:

DELETE /index_one,index_twoDELETE /index_*

你甚至可以这样删除

全部
索引:

DELETE /_allDELETE /*

类型和映射

类型
在 Elasticsearch 中表示一类相似的文档,类型由名称和映射( mapping)组成。

映射
 mapping, 就像数据库中的 schema ,描述了文档可能具有的字段或属性、 每个字段的数据类型—比如 string, integerdate

为了能够将时间字段视为时间,数字字段视为数字,字符串字段视为全文或精确值字符串, Elasticsearch 需要知道每个字段中数据的类型。

简单字段类型:

  • 字符串: text (在elaticsearch 2.x版本中,为string类型)

  • 整数 : byte, short, integer, long

  • 浮点数: float, double

  • 布尔型: boolean

  • 日期: date

下面建立一个文章映射:

curl -X PUT 127.0.0.1:9200/articles/_mapping/article -H 'Content-Type: application/json' -d'
{
     "_all": {
          "analyzer": "ik_max_word"
      },
      "properties": {
          "article_id": {
              "type": "long",
              "include_in_all": "false"
          },
          "user_id": {
              "type": "long",
              "include_in_all": "false"
          },
          "title": {
              "type": "text",
              "analyzer": "ik_max_word",
              "include_in_all": "true",
              "boost": 2
          },
          "content": {
              "type": "text",
              "analyzer": "ik_max_word",
              "include_in_all": "true"
          },
          "status": {
              "type": "integer",
              "include_in_all": "false"
          },
          "create_time": {
              "type": "date",
              "include_in_all": "false"
          }
      }
}
'
  • _all字段是把所有其它字段中的值,以空格为分隔符组成一个大字符串,然后被分析和索引,但是不存储,也就是说它能被查询,但不能被取回显示。_all允许在不知道要查找的内容是属于哪个具体字段的情况下进行搜索。

  • analyzer指明使用的分析器

    索引时的顺序如下:

    • 字段映射里定义的 analyzer

    • 否则索引设置中名为 default 的分析器,默认为standard 标准分析器

      在搜索时,顺序有些许不同:

    • 查询自己定义的 analyzer

    • 否则字段映射里定义的 analyzer

    • 否则索引设置中名为 default 的分析器,默认为standard 标准分析器

  • include_in_all 参数用于控制 _all 查询时需要包含的字段。默认为 true。

  • boost可以提升查询时计算相关性分数的权重。例如title字段将是其他字段权重的两倍。

查看映射

curl 127.0.0.1:9200/articles/_mapping/article?pretty

映射修改

一个类型映射创建好后,可以为类型增加新的字段映射

curl -X PUT 127.0.0.1:9200/articles/_mapping/article -H 'Content-Type:application/json' -d '
{
  "properties": {
    "new_tag": {
      "type": "text"
    }
  }
}
'

但是不能修改已有字段的类型映射,原因在于elasticsearch已按照原有字段映射生成了反向索引数据,类型映射改变意味着需要重新构建反向索引数据,所以并不能再原有基础上修改,只能新建索引库,然后创建类型映射后重新构建反向索引数据。

例如,将status字段类型由integer改为byte会报错

curl -X PUT 127.0.0.1:9200/articles/_mapping/article -H 'Content-Type:application/json' -d '
{
  "properties": {
    "status": {
      "type": "byte"
    }
  }
}
'

需要从新建立索引

curl -X PUT 127.0.0.1:9200/articles_v2 -H 'Content-Type: application/json' -d'
{
   "settings" : {
      "index": {
          "number_of_shards" : 3,
          "number_of_replicas" : 1
       }
   }
}
'

curl -X PUT 127.0.0.1:9200/articles_v2/_mapping/article -H 'Content-Type: application/json' -d'
{
     "_all": {
          "analyzer": "ik_max_word"
      },
      "properties": {
          "article_id": {
              "type": "long",
              "include_in_all": "false"
          },
          "user_id": {
               "type": "long",
              "include_in_all": "false"
          },
          "title": {
              "type": "text",
              "analyzer": "ik_max_word",
              "include_in_all": "true",
              "boost": 2
          },
          "content": {
              "type": "text",
              "analyzer": "ik_max_word",
              "include_in_all": "true"
          },
          "status": {
              "type": "byte",
              "include_in_all": "false"
          },
          "create_time": {
              "type": "date",
              "include_in_all": "false"
          }
      }
}
'
重新索引数据
curl -X POST 127.0.0.1:9200/_reindex -H 'Content-Type:application/json' -d '
{
  "source": {
    "index": "articles"
  },
  "dest": {
    "index": "articles_v2"
  }
}
'
为索引起别名

为索引起别名,让新建的索引具有原索引的名字,可以让应用程序零停机。

curl -X DELETE 127.0.0.1:9200/articles  # 先删除原有的库
curl -X PUT 127.0.0.1:9200/articles_v2/_alias/articles # 给新库起别名

查询索引别名

# 查看别名指向哪个索引
curl 127.0.0.1:9200/*/_alias/articles
​# 查看哪些别名指向这个索引
curl 127.0.0.1:9200/articles_v2/_alias/*

文档数据的增删改查

  • 增加文档(数据)

    • 自己指定主键

      PUT /{index}/{type}/{id}
      {
        "field": "value",
        ...
      }
      
      curl -X PUT 127.0.0.1:9200/articles/article/150000 -H 'Content-Type:application/json' -d '
      {
        "article_id": 150000,  "user_id": 1,
        "title": "Elaticsearch权威指南",
        "content": "巴拉巴拉",
        "status": 2,
        "create_time": "2019-07-13"
      }'
      
      # 返回值
      {"_index":"articles","_type":"article","_id":"150000","_version":1,"result":"created","_shards":{"total":2,"successful":1,"failed":0},"created":true}

      1、_index:指的是在哪个索引库创建文档

      2、_type:指的是在哪个映射类型创建文档

      3、_id:指的文档id

    • 不指定主键

      PUT /{index}/{type}{  "field": "value",  ...}
  • 查看文档

    curl 127.0.0.1:9200/articles/article/150000?pretty
    ​# 获取一部分
    curl 127.0.0.1:9200/articles/article/150000?_source=title,content\&pretty
     # 返回值
    {  "_index" : "articles",  "_type" : "article",  "_id" : "150000",  "_version" : 1,  "found" : true,  "_source" : {    "article_id" : 150000,    "user_id" : 1,    "title" : "Elaticsearch权威指南",    "content" : "巴拉巴拉",    "status" : 2,    "create_time" : "2019-04-03"  }}
  • 判断文档是否存在

    curl -i -X HEAD 127.0.0.1:9200/articles/article/150000​# 存在 200状态码# 不存在 404状态码
  • 更新文档

    curl -X PUT 127.0.0.1:9200/articles/article/150000 -H 'Content-Type:application/json' -d '
    {
      "title": "python必须是世界上最好的语言"
    }'
    # 如果这样修改,那么真个文档中的内容就剩一条数据了
    {
      "_index" : "articles",
      "_type" : "article",
      "_id" : "150000",
      "_version" : 2,
      "found" : true,
      "_source" : {
        "title" : "python必须是世界上最好的语言"
      }
    }
    # 将文章整体修改
    curl -X PUT 127.0.0.1:9200/articles/article/150000 -H 'Content-Type:application/json' -d '
    {
      "article_id": 150000,
      "user_id": 1,
      "title": "python必须是世界上最好的语言",
      "content": "确实如此",
      "status": 2,
      "create_time": "2019-04-03"
    }'

    _version:每次修改版本都会+1

  • 更新文档

    curl -X POST 127.0.0.1:9200/articles/article/150000/_update -H 'Content-Type:application/json' -d '
    {
       "doc" : {
          "title" : "aaa",
          "title": "python必须是世界上最好的语言"
       }
    }'
  • 删除文档

    curl -X DELETE 127.0.0.1:9200/articles/article/150000
  • 取回多个文档

    curl -X GET 127.0.0.1:9200/_mget -d '
    {
      "docs": [
        {
          "_index": "articles",
          "_type": "article",
          "_id": 150000
        },
        {
          "_index": "articles",
          "_type": "article",
          "_id": 150001
        }
      ]
    }'

logstash导入工具使用

  • 安装java

  • 直接使用rpm

    wget https:``//download``.elastic.co``/logstash/logstash/packages/centos/logstash-2``.4.0.noarch.rpm
  • logstash安装

    sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
  • 在 /etc/yum.repos.d/ 中创建logstash.repo文件 ——> 更改yum源

    [logstash-6.x]
    name=Elastic repository for 6.x packages
    baseurl=https://artifacts.elastic.co/packages/6.x/yum
    gpgcheck=1
    gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
    enabled=1
    autorefresh=1
    type=rpm-md
  • 安装logstash

    sudo yum install logstash
  • cd /usr/share/logstash/bin/
    sudo ./logstash-plugin install logstash-input-jdbc
    sudo ./logstash-plugin install logstash-output-elasticsearch
    scp mysql-connector-java-8.0.13.tar.gz python@自己的ip地址:~/
    tar -zxvf mysql-connector-java-8.0.13.tar.gz
  • 从MySQL导入数据到Elasticsearch

    # 创建配置文件logstash_mysql.conf
    input{
         jdbc {
             jdbc_driver_library => "/home/python/mysql-connector-java-8.0.13/mysql-connector-java-8.0.13.jar"
             jdbc_driver_class => "com.mysql.jdbc.Driver"
             jdbc_connection_string => "jdbc:mysql://127.0.0.1:3306/数据库名?tinyInt1isBit=false"
             jdbc_user => "root"
             jdbc_password => "mysql"
             jdbc_paging_enabled => "true"
             jdbc_page_size => "1000"
             jdbc_default_timezone =>"Asia/Shanghai"
             statement => "sql语句"
             use_column_value => "true"
             tracking_column => "article_id"
             clean_run => true
         }
    }
    output{
          elasticsearch {
             hosts => "127.0.0.1:9200"
             index => "articles"
             document_id => "%{article_id}"
             document_type => "article"
          }
          stdout {
             codec => json_lines
         }
    }
    
    # 运行配置文件
    sudo /usr/share/logstash/bin/logstash -f ./logstash_mysql.conf

    查询方法

    • 基本查询

      • 根据文档ID

          curl -X GET 127.0.0.1:9200/articles/article/1?pretty  # pretty将结果格式化输出  curl -X GET 127.0.0.1:9200/articles/article/1?_source=title,user_id\&pretty  curl -X GET 127.0.0.1:9200/articles/article/1?_source=false\&pretty
      • 查询所有

        curl -X GET 127.0.0.1:9200/articles/article/_search?_source=title,user_id\&pretty # 查询所有文档,显示title,user_id
      • 分页

        • from 起始

        • size 每页数量

          curl -X GET 127.0.0.1:9200/articles/article/_search?_source=title,user_id\&size=3\&pretty
          curl -X GET 127.0.0.1:9200/articles/article/_search?_source=title,user_id\&size=3\&from=2\&pretty
      • 全文检索

        curl -X GET 127.0.0.1:9200/articles/article/_search?q=content:python%20web\&_source=title,article_id\&pretty
        
         curl -X GET 127.0.0.1:9200/articles/article/_search?q=title:python%20web,content:python%20web\&_source=title,article_id\&pretty
        
         curl -X GET 127.0.0.1:9200/articles/article/_search?q=_all:python%20web\&_source=title,article_id\&pretty
        

    • 高级查询

      • 全文检索 match

          curl -X GET 127.0.0.1:9200/articles/article/_search?pretty -d'
          {
              "from": 0,
              "size": 5,
              "_source": ["article_id","title"],
              "query" : {
                  "match" : {
                      "title" : "python web"
                  }
              }
          }'
        # 匹配结果·
          curl -X GET 127.0.0.1:9200/articles/article/_search?pretty -d'
          {
              "from": 0,
              "size": 5,
              "_source": ["article_id","title"],
              "query" : {
                  "match" : {
                      "_all" : "python web 编程"
                  }
              }
          }'
        
        
      • 短语搜索 match_phrase —整个python web 不拆分

        curl -X GET 127.0.0.1:9200/articles/article/_search?pretty -d'
          {
              "size": 5,
              "_source": ["article_id","title"],
              "query" : {
                  "match_phrase" : {
                      "_all" : "python web"
                  }
              }
          }'
      • 精确查找 term

        curl -X GET 127.0.0.1:9200/articles/article/_search?pretty -d'
          {
              "size": 5,
              "_source": ["article_id","title", "user_id"],
              "query" : {
                  "term" : {
                      "user_id" : 1
                  }
              }
          }'
      • 范围查找 range

          curl -X GET 127.0.0.1:9200/articles/article/_search?pretty -d'
          {
              "size": 5,
              "_source": ["article_id","title", "user_id"],
              "query" : {
                  "range" : {
                      "article_id": { 
                          "gte": 3,
                          "lte": 5
                      }
                  }
              }
          }'
      • 高亮搜索 highlight

        curl -X GET 127.0.0.1:9200/articles/article/_search?pretty -d '
          {
              "size":2,
              "_source": ["article_id", "title", "user_id"],
              "query": {
                  "match": {
                       "title": "python web 编程"
                   }
               },
               "highlight":{
                    "fields": {
                        "title": {}
                    }
               }
          }
          '
        # 使用<em>Web</em>
      • 组合查询

        • must:文档必须匹配这些条件才能被包含进来

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

        • should:如果满足这些语句中的任意语句,将增加 _score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分。

        • filter:必须匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。

        curl -X GET 127.0.0.1:9200/articles/article/_search?pretty -d '
        {
          "_source": ["title", "user_id"],
          "query": {
              "bool": {
                  "must": {
                      "match": {
                          "title": "python web"
                      }
                  },
                  "filter": {
                      "term": {
                          "user_id": 2
                      }
                  }
              }
          }
        }
        '
      • 排序

        curl -X GET 127.0.0.1:9200/articles/article/_search?pretty -d'
          {
              "size": 5,
              "_source": ["article_id","title"],
              "query" : {
                  "match" : {
                      "_all" : "python web"
                  }
              },
              "sort": [
                  { "create_time":  { "order": "desc" }},
                  { "_score": { "order": "desc" }}
              ]
          }'
      • boost 提升权重,优化排序

        curl -X GET 127.0.0.1:9200/articles/article/_search?pretty -d'
          {
              "size": 5,
              "_source": ["article_id","title"],
              "query" : {
                  "match" : {
                      "title" : {
                          "query": "python web",
                          "boost": 4
                      }
                  }
              }
          }'

    python操作elasticsearch的方法

    安装:

    pip install elasticsearch

    对于elasticsearch 5.x 版本 需要按以下方式导入

from elasticsearch5 import Elasticsearch

# elasticsearch集群服务器的地址
ES = [
    '127.0.0.1:9200'
]

# 创建elasticsearch客户端
es = Elasticsearch(
    ES,
    # 启动前嗅探es集群服务器
    sniff_on_start=True,
    # es集群服务器结点连接异常时是否刷新es结点信息
    sniff_on_connection_fail=True,
    # 每60秒刷新结点信息
    sniffer_timeout=60
)

搜索使用

query = {
    'query': {
        'bool': {
            'must': [
                {'match': {'_all': 'python web'}}
            ],
            'filter': [
                {'term': {'status': 2}}
            ]
        }
    }
}
ret = es.search(index='articles', doc_type='article', body=query)

运行程序新增数据,导入搜索库

doc = {
         ‘key’:'value' 
      }
es.index(index='articles', doc_type='article', body=doc, id='xxx')

自动补全索引库(联想提示)

拼写纠错

# 对于已经建立的articles索引库,elasticsearch还提供了一种查询模式,suggest建议查询模式
curl 127.0.0.1:9200/articles/article/_search?pretty -d '
{
    "from": 0,
    "size": 10,
    "_source": false,
    // 建议
    "suggest": {
        "text": "phtyon web",
        // 自定义返回字段名称
        "word-phrase": {
            "phrase": {
                "field": "_all",
              	// 提供一条建议
                "size": 1
            }
        }
    }
}'

# 返回结果
{
  "took" : 111,
  "timed_out" : false,
  "_shards" : {
    "total" : 3,
    "successful" : 3,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 0,
    "max_score" : 0.0,
    "hits" : [ ]
  },
  "suggest" : {
    "word-phrase" : [
      {
        "text" : "phtyon web",
        "offset" : 0,
        "length" : 10,
        "options" : [
          {
            "text" : "python web",
            "score" : 0.0011777458
          }
        ]
      }
    ]
  }
}

自动补全(需要额外建立索引库)

curl -X PUT 127.0.0.1:9200/completions -H 'Content-Type: application/json' -d'
{
   "settings" : {
       "index": {
           "number_of_shards" : 3,
           "number_of_replicas" : 1
       }
   }
}
'

创建words类型映射(表)

curl -X PUT 127.0.0.1:9200/completions/_mapping/words -H 'Content-Type: application/json' -d'
{
     "words": {
          "properties": {
              "suggest": {
                  "type": "completion",
                  "analyzer": "ik_max_word"
              }
          }
     }
}
'

使用使用logstash添加数据,然后自动补全建议查询:

curl 127.0.0.1:9200/completions/words/_search?pretty -d '
{
    "suggest": {
        "title-suggest" : {
            "prefix" : "pyth", 
            "completion" : { 
                "field" : "suggest" 
            }
        }
    }
}
'

自动补全的实现:先将关键字在completions 自动补全索引库中查询,获取建议的补全信息,如没有获取到补全信息,可能表示用户输入的关键词有拼写错误,在索引库中进行纠错建议查询。

参考链接:

《ES权威指南》es.xiaoleilu.com/030_Data/05…