自学内容网 自学内容网

ElasticSearch搜索引擎使用指南

一、ES数据基础类型

1、数据类型

字符串

主要包括: text和keyword两种类型,keyword代表精确值不会参与分词,text类型的字符串会参与分词处理

数值

包括: long, integer, short, byte, double, float

布尔值

boolean

时间

date

数组

数组类型不需要专门定义,只要插入的字段值是json数组就行

GEO类型

主要涉及地理信息检索、多边形区域的表达

2、text&keyword使用注意

text类型,支持全文搜索,因为text涉及分词,所以可以配置使用什么分词器,尤其涉及中文分词。

实际项目中,如果不需要模糊搜索的字符类型,可以选择keyword类型,例如:手机号、email、微信的openid等等,如果选text类型,可能会出现搜出一大堆相似的数据,而且不是精确的数据。

二、query语法

query子句主要用于编写查询条件,类似于SQL中的where语句。

query子句主要用于编写类似SQL的where语句,支持布尔查询(and/or)、IN、全文搜索、模糊匹配、范围查询(大于/小于)。

其中:text类型字段支持分词,可以使用模糊查询。keyword类型只能做等值查询,不能进行分词。

1、match类like匹配

1.1 match匹配单个字段

使用match实现全文搜索。类似于SQL中的like操作。

简单使用的语法:

GET /{索引名}/_search
{
  "query": {
    "match": {
      "{FIELD}": "{TEXT}"
    }
  }
}

说明:
{FIELD} - 就是我们需要匹配的字段名
{TEXT} - 就是我们需要匹配的内容

例子:

GET /article/_search
{
    "query": {
        "match" : {
            "title" : "ES教程"
        }
    }
}

article索引中,title字段匹配“ES教程”的所有文档。

如果title字段的数据类型是text类型,搜索关键词会进行分词处理。

等价SQL(假设"ES教程"没有进行分词):

select * from article where title like '%ES教程%'

1.2 multi_match多字段匹配

例子:

GET /article/_search
{
  "query": {
    "multi_match": {
      "query": "斯柯达前轮制动器",
      "fields":[
        "doc_title",
        "doc_content"
      ]
    }
  }
}

等价SQL:

select * from article where doc_title like '%<斯柯达前轮制动器的分词>%' or doc_content like '%<斯柯达前轮制动器的分词>%'

因为 斯柯达前轮制动器的分词 会有很多,所以实际上也会有很多的like,而不仅仅是上面的两个like。

2、term精确匹配单个字段

使用term实现精确匹配

如果想要类似SQL语句中的等值匹配,不需要进行分词处理,例如:订单号、手机号、时间字段,不需要分值处理,只要精确匹配。

语法:

GET /{索引名}/_search
{
  "query": {
    "term": {
      "{FIELD}": "{VALUE}"
    }
  }
}

{FIELD} - 就是我们需要匹配的字段名
{VALUE} - 就是我们需要匹配的内容,除了TEXT类型字段以外的任意类型

例子:

GET /order_v2/_search
{
  "query": {
    "term": {
      "order_no": "202003131209120999"
    }
  }
}

搜索订单号order_no = "202003131209120999"的文档。

类似SQL语句:

select * from order_v2 where order_no = "202003131209120999"

3、terms实现SQL的in语句

如果我们要实现SQL中的in语句,一个字段包含给定数组中的任意一个值就匹配。

语法:

GET /order_v2/_search
{
  "query": {
    "terms": {
      "{FIELD}": [
        "{VALUE1}",
        "{VALUE2}"
      ]
    }
  }
}

说明:

{FIELD} - 就是我们需要匹配的字段名
{VALUE1}, {VALUE2} … {VALUE N} - 就是我们需要匹配的内容,除了TEXT类型字段以外的任意类型。

例子:

GET /order_v2/_search
{
  "query": {
    "terms": {
      "shop_id": [123,100,300]
    }
  }
}

搜索order_v2索引中,shop_id字段,只要包含[123,100,300]其中一个值,就算匹配。

类似SQL语句:

select * from order_v2 where shop_id in (123,100,300)

4、range范围查询

通过range实现范围查询,类似SQL语句中的>, >=, <, <=表达式。

语法:

GET /{索引名}/_search
{
  "query": {
    "range": {
      "{FIELD}": {
        "gte": 10, 
        "lte": 20
      }
    }
  }
}

参数说明:

{FIELD} - 字段名

gte范围参数 - 等价于>=

lte范围参数 - 等价于 <=

范围参数可以只写一个,例如:仅保留 “gte”: 10, 则代表 FIELD字段 >= 10

范围参数如下:

gt - 大于 ( > )
gte - 大于且等于 ( >= )
lt - 小于 ( < )
lte - 小于且等于 ( <= )

例子:

GET /order_v2/_search
{
  "query": {
    "range": {
      "shop_id": {
        "gte": 10,
        "lte": 200
      }
    }
  }
}

查询order_v2索引中,shop_id >= 10 且 shop_id <= 200的文档。类似SQL:

select * from order_v2 where shop_id >= 10 and shop_id <= 200

5、bool组合查询

前面的例子都是设置单个字段的查询条件,如果想要编写类似SQL的Where语句组合多个字段的查询条件,可以使用bool语句。

5.1 bool查询基本语法结构

语法:

GET /{索引名}/_search
{
  "query": {
    "bool": { // bool查询
      "must": [], // must条件,类似SQL中的and, 代表必须匹配条件
      "must_not": [], // must_not条件,跟must相反,必须不匹配条件
      "should": [] // should条件,类似SQL中or, 代表匹配其中一个条件
    }
  }
}

must、must_not和should条件的参数都是一个数组,意味着他们都支持设置多个条件。

同时,前面介绍的单个字段的匹配语句,都可以用在bool查询语句中进行组合。

5.2 must条件

类似SQL的and,代表必须匹配的条件。

语法:

GET /{索引名}/_search
{
  "query": {
    "bool": {
      "must": [
         {匹配条件1},
         {匹配条件2},
         ...可以有N个匹配条件...
        ]
    }
  }
}

例子:

GET /order_v2/_search
{
  "query": {
    "bool": {
      "must": [
          {
            "term": {
              "order_no":  "202003131209120999"
            }
          },
          {
            "term": {
              "shop_id":  123
            }
          }
        ]
    }
  }
}

这里的Must条件,使用了term精确匹配,等价SQL:

select * from order_v2 where order_no="202003131209120999" and shop_id=123

5.3 must_not条件

跟must的作用相反,语法类似。

5.4 should条件

类似SQL中的 or, 只要匹配其中一个条件即可。

语法:

GET /{索引名}/_search
 {
   "query": {
     "bool": {
       "should": [
          {匹配条件1},
          {匹配条件2},
          …可以有N个匹配条件…
         ]
     }
   }
 }

例子:

GET /order_v2/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "order_no": "202003131209120999"
          }
        },
        {
          "term": {
            "order_no": "22222222222222222"
          }
        }
      ]
    }
  }
}

等价SQL:

select * from order_v2 where order_no="202003131209120999" or order_no="22222222222222222"

5.5 bool综合例子

GET /order_v2/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "bool": {
            "must": [
              {
                "term": {
                  "order_no": "2020031312091209991"
                }
              },
              {
                "range": {
                  "shop_id": {
                    "gte": 10,
                    "lte": 200
                  }
                }
              }
            ]
          }
        },
        {
          "terms": {
            "tag": [
              1,
              2,
              3,
              4,
              5,
              12
            ]
          }
        }
      ]
    }
  }
}

等价SQL:

select * from order_v2 where (order_no='202003131209120999' and (shop_id>=10 and shop_id<=200)) or tag in (1,2,3,4,5)

6、wildcard通配符查询

wildcard 关键字: 通配符查询 ? 用来匹配一个任意字符 * 用来匹配多个任意字符。

例子:

GET /xizi/emp/_search
    {
      "query": {
        "wildcard": {
          "name": {
            "value": "xi*"
          }
        }
      }
    }

7、fuzzy模糊查询

fuzzy 模糊查询,最大模糊错误必须在0-2之间  

搜索关键词长度为 2 不允许存在模糊 0

 搜索关键词长度为3-5 允许一次模糊 0 1  

搜索关键词长度大于5 允许最大2模糊

例子:

GET /xizi/emp/_search
    {
      "query": {
        "fuzzy": {
          "name":"xizi"
        }
      }
    }

8、额外限制条件

8.1 _source指定返回字段

例子1:

get lib3/user/_search
{
  "_source":["name","age"],
  "query":{
    "match": {
      "interests": "changge"
    }
  }

结果只返回索引中name和age字段信息

例子2:

get lib3/user/_search
{
  "query":{
    "match_all": {}
  },
  "_source":{
     "includes": "addr*",
     "excludes": ["name","bir*"]
  }
}

显示要的字段、去除不需要的字段、可以使用通配符*。

8.2 boost查询的权重

8.3 min_similarity设置匹配的最小相似度

8.4 highlight高亮搜索结果

例子:

get data_info/_search
{
  "_source":["doc_title","doc_content"],
  "query": {
    "match": {
      "doc_content": "斯柯达前轮制动器"
    }
  },
  "highlight":{
    "fields":{
      "doc_content":{}
    }
  }
}

返回结果:

8.5 size指定返回条数

ES默认返回10条结果。

例子:

get data_info/_search
{
  "query": {
    "match": {
      "doc_content": "斯柯达前轮制动器"
    }
  },
  "size": 2
}

结果中只有2条信息。

8.6 from分页查询

from 关键字: 用来指定起始返回位置,和size关键字连用可实现分页效果。

例子:

get data_info/_search
{
  "query": {
    "match": {
      "doc_content": "斯柯达前轮制动器"
    }
  },
  "size": 2,
  "from": 3
}

三、全文搜索

1、概念

平时我们使用SQL like语句搜索一些文本、字符串是否包含指定的关键词,如果两篇文章都包含我们的关键词,那么具体哪篇文章内容的相关度更高?这个SQL的like语句是做不到的,更别说like语句的性能问题了。

ES通过分词、相关度计算可以解决这个问题,ES内置了一些相关度算法,大致上意思是:如果一个关键词在一篇文章出现的频率高,并且在其他文章中出现少,那说明这个关键词与这篇文章的相关度很高。

ES对于text类型的字段,在插入数据的时候,会进行分词处理,然后根据分词的结果索引文档,当我们搜索text类型字段的时候,也会先对搜索关键词进行分词处理、然后根据分词的结果去搜索。

2、分词效果测试

语法:

GET /_analyze
{
  "text": "需要分词的内容",
  "analyzer": "分词器"
}

例子:

GET http://xx.elasticsearch.aliyuncs.com:9200/_analyze
{
"text":"上海大学",
"analyzer": "standard"
}

使用standard分词器,对"上海大学"进行分词,下面是输出结果:

{
"tokens": [
{
"token": "上",
"start_offset": 0,
"end_offset": 1,
"type": "<IDEOGRAPHIC>",
"position": 0
},
{
"token": "海",
"start_offset": 1,
"end_offset": 2,
"type": "<IDEOGRAPHIC>",
"position": 1
},
{
"token": "大",
"start_offset": 2,
"end_offset": 3,
"type": "<IDEOGRAPHIC>",
"position": 2
},
{
"token": "学",
"start_offset": 3,
"end_offset": 4,
"type": "<IDEOGRAPHIC>",
"position": 3
}
]
}

token就是分解出来的关键词。


原文地址:https://blog.csdn.net/benben044/article/details/136394190

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!