Elasticsearch学习系列三(搜索案例实战)

博客 动态
0 165
优雅殿下
优雅殿下 2022-06-22 10:00:52
悬赏:0 积分 收藏

Elasticsearch学习系列三(搜索案例实战)

Query DSL

Es提供了基于JSON的完整查询DSL(Domain Specific Language 特定域的语言)来定义查询。将查询DSL视为查询的AST(抽象语法树)。它由两种子句组成:

  • 叶子查询子句

叶子查询子句,在特定域中寻找特定的值,如match、term或range查询

  • 复合查询子句

复合查询子句包装其他叶子查询或复合查询,并用于以逻辑方式组合多个查询。如bool、dis_max、constant_score查询

1. 查询所有

POST /索引名称/_search{  "query":{    "match_all": {}  }}

查询结果示例:

{  "took" : 1,  "timed_out" : false,  "_shards" : {    "total" : 1,    "successful" : 1,    "skipped" : 0,    "failed" : 0  },  "hits" : {    "total" : {      "value" : 3,      "relation" : "eq"    },    "max_score" : 1.0,    "hits" : [      {        "_index" : "test-demo1",        "_type" : "_doc",        "_id" : "1",        "_score" : 1.0,        "_source" : {          "name" : "百度3",          "job" : "运营",          "amt" : "3000.34",          "logo" : "http://www.lgstatic.com/ttasdf2",          "createTime" : "20220303230000"        }      }      ...省略2条数据    ]  }}
  • took:查询花费时间,单位是毫秒
  • time_out:是否超时
  • _shards:分片信息
  • hits:搜索结果总览对象
    • total:搜索到的总条数
    • max_score:所有结果中文档得分的最高分
    • hits:搜索结果的文档对象数组,每个元素是一条搜索到的文档信息
      • _index:索引库
      • _type:文档类型
      • _id:文档id
      • _score:文档得分
      • _source:文档的源数据

2. 全文搜索

全文搜索能够搜索已分析的文本字段,如电子邮件正文、商品描述等。

先造一些测试数据:

PUT /item{  "settings": {},  "mappings": {    "properties": {      "title": {        "type": "text",        "analyzer": "ik_max_word"      },      "images": {        "type": "keyword"      },      "price": {        "type": "float"      }    }  }}
POST /item/_doc/{"title": "小米电视4A","images": "http://image.lagou.com/12479122.jpg","price": 4288}POST /item/_doc/{"title": "小米手机","images": "http://image.lagou.com/12479122.jpg","price": 2688}POST /item/_doc/{"title": "苹果手机","images": "http://image.lagou.com/12479122.jpg","price": 5699}
2.1 匹配搜索
  • or关系

match类型的查询,会把查询条件分词,多个词条之间是or的关系。如下面的例子,会根据小米和手机分别去搜索,能搜出3条数据。

POST /item/_search{  "query":{    "match": {      "title": "小米手机"    }  }}
  • and关系
POST /item/_search{  "query":{    "match": {      "title": {        "query": "小米手机",        "operator":"and"      }    }  }}
2.2 短语搜索

match_phrase查询用来对一个字段进行短语查询,可以指定analyzer、slop移动因子

POST /item/_search{  "query":{   "match_phrase": {     "title": "小米手机"   }  }}

带slop:

POST /item/_search{  "query":{   "match_phrase": {     "title": {       "query": "手机小米",       "slop":2     }   }  }}

slop参数告诉match_phrase查询词条能够相隔多远时仍然将文档视为匹配。相隔多远的意思是,你需要移动一个词条多少次来让查询和文档匹配

2.3 query_string 查询

query string提供了无需指定某字段而对文档全文进行匹配查询的一个高级查询,同时可以指定在哪些字段上进行匹配。

GET /item/_search{  "query": {    "query_string": {      "query": "2688"    }  }}GET /item/_search{  "query": {    "query_string": {      "default_field": "price",       "query": "2688"    }  }}GET /item/_search{  "query": {    "query_string": {      "default_field": "title",       "query": "手机 OR 小米"    }  }}GET /item/_search{  "query": {    "query_string": {      "default_field": "title",       "query": "手机 and 小米"    }  }}#模糊查询GET /item/_search{  "query": {    "query_string": {      "default_field": "title",       "query": "小米~1"    }  }}#多字段支持GET /item/_search{  "query": {    "query_string": {      "fields": ["title","price"],       "query": "2699"    }  }}
2.4 多字段匹配搜索

如果你需要在多个字段上进行文本搜索,可用multi_match。

GET /item/_search{  "query": {    "multi_match": {      "query": "2688",      "fields": ["title","price"]    }  }}#还可以使用*配置GET /item/_search{  "query": {    "multi_match": {      "query": "2688",      "fields": ["title","pri*"]    }  }}

3. 词条搜索

可以使用term-level queries根据结构化数据中的精确值查找文档。term-level queries不分析搜索词。搜索词与存储在字段中的词需要完全匹配

3.1 词条普通搜索

用于查询指定字段包含某个搜索词的文档

POST /item/_search{  "query": {    "term": {      "title":"小米"    }  }}
3.2 词条集合搜索
POST /item/_search{  "query": {    "terms": {      "title": ["小米","电视"]    }  }}
3.3 范围搜索
  • gte:大于等于
  • gt:大于
  • lte:小于等于
  • lt:小于
  • boost:查询权重
POST /item/_search{  "query": {    "range": {      "price": {        "gte": 10,        "lte": 3000      }    }  }}#日期范围POST /item/_search{  "query": {    "range": {      "createTime": {        "gte": "2022-01-01",        "lte": "2022-02-01",        "format": "yyyy-MM-dd"      }    }  }}
3.4 不为空搜索
GET /item/_search{  "query": {    "exists": {      "field": "price"    }  }}
3.5 词项前缀搜索
GET /item/_search{  "query": {    "prefix": {      "title": {        "value": "小米"      }    }  }}
3.6 通配符搜索
GET /item/_search{  "query": {    "wildcard": {      "title":"小*"    }  }}
3.7 正则搜索
GET /item/_search{  "query": {    "regexp": {      "title":"小米[a-z0-9]"    }  }}
3.8 模糊搜索
GET /item/_search{  "query": {    "fuzzy": {      "title": "手机"    }  }}#错别字纠正GET /item/_search{  "query": {    "fuzzy": {      "title": {        "value": "大米",        "fuzziness": 1      }    }  }}
3.9 ids搜索
GET /item/_search{  "query": {    "ids": {      "values": ["t76YgYEB9TD2fYkcLzha","tb6XgYEB9TD2fYkc6zhx"]    }  }}

4. 复合搜索

4.1 constant_score,用来包装另一个查询,将查询匹配的文档的评分设为一个常值
GET /item/_search{  "query": {   "constant_score": {     "filter": {       "term": {         "title": "小米"       }     },     "boost": 1.2   }  }}
4.2 bool query,用bool组合多个查询子句为一个查询。
  • must:必须满足
  • filter:必须满足,但执行的是filter上下文,不参与、影响评分
  • should:或
  • must_not:必须不满足,在filter上下文中执行,不参与、不影响评分
POST /item/_search{  "query": {    "bool": {      "must": [        {          "match": {            "title": "小米"          }        }      ], "filter": {        "term": {          "title": "电视"        }      },"must_not": [        {          "range": {            "price": {              "gte": 4200,              "lte": 4300            }          }        }      ]      ,"minimum_should_match": 0    }  }}

minimum_should_match代表了最小匹配精度,如果设置为1,代表should语句中至少需要有一个条件满足。

5. 排序

5.1 相关性评分排序

默认情况下,返回的结果是按照相关性进行排序的。默认排序是_score降序

# 按照评分升序GET /item/_search{  "query": {    "match_all": {}  },  "sort":[{    "_score":{      "order":"asc"    }  }  ]}#根据字段值排序GET /item/_search{  "query": {    "match_all": {}  },  "sort":[{    "price":{      "order":"asc"    }  }  ]}#多个字段的排序GET /item/_search{  "query": {    "match_all": {}  },  "sort":[{    "price":{      "order":"asc"    }  },{    "createTime": {      "order":"desc"    }  }  ]}

6.分页

size:每页显示多少条

from:当前页起始索引

POST /item/_search{  "query": {    "match_all": {}  }  ,"size": 2,  "from": 0}

7. 高亮

POST /item/_search{  "query": {    "match": {      "title": "小米"    }  },  "highlight": {    "pre_tags": "<font color='pink'>",    "post_tags": "</font>",    "fields": [{"title":{}}]  }}
  • pre_tags:前置标签
  • post_tags:后置标签
  • fields:需要高亮的字段
    • title:这里声明title字段需要高亮

8. 文档批量操作

8.1 mget批量查询

不同的索引

GET /_mget{  "docs":[    {      "_index":"item",      "_id":"tb6XgYEB9TD2fYkc6zhx"    },    {      "_index":"test-location",      "_id":1    }    ]}

相同的索引

POST /test-location/_search{  "query": {    "ids": {      "values": ["1","2"]    }  }}
8.2 bulk批量增删改

语法:

POST /_bulk{"action": {"metadata"}}{"data"}

示例:

POST /_bulk  {"delete":{"_index":"item","_id":"tb6XgYEB9TD2fYkc6zhx"}}  {"create":{"_index":"item","_id":"1"}}  {"title":"华为电脑","price":2333}  {"update":{"_index":"item","_id":2}}  {"doc":{"title":"冰箱"}}
  • delete:删除一个文档,删除没有请求体,只需要一个json串就行
  • create:相当于强制创建
  • index:普通的PUT操作,可以创建也可以全量替换
  • update:执行的是局部更新

格式:每个json不能换行,相邻json必须换行

隔离:每个操作互不影响,操作失败的行会返回其失败信息

实际用法:bulk请求一次不要太大,否则一下积压到内存中,性能会下降。所以,一次请求几千个操作、大小在几M正好。bulk会将要处理的数据载入内存中,所以数据量是有限的,最佳的数据量不是一个确定的数据,它取决于你的硬件,你的文档大小以及复杂性,你的索引以及搜索的负载。一般建议是1000-5000个文档,大小建议是5-15MB,默认不能超过100M,可以在es的配置文件(ES的config下的elasticsearch.yml)中配置。

http.max_content_length: 10mb

posted @ 2022-06-22 09:43 女友在高考 阅读(0) 评论(0) 编辑 收藏 举报
回帖
    优雅殿下

    优雅殿下 (王者 段位)

    2018 积分 (2)粉丝 (47)源码

    小小码农,大大世界

     

    温馨提示

    亦奇源码

    最新会员