07.Elasticsearch应用(七)

发布时间:2024年01月24日

Elasticsearch应用(七)

1.目标

讲解ES的DSL查询

2.查询文档的方式

  1. REST风格查询: 在请求URL中,直接将参数带过去
  2. DSL查询: Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询
  3. SQL查询: 在ES7之后,支持SQL语句查询文档。开源版本的ES并不支持通过Java操作SQL进行查询,如果需要操作SQL查询,则需要氯金(购买白金版)

3.DSL查询分类

  • 全文检索(full text):全文检索查询,利用分词器对用户输入的内容进行分词,然后去倒排索引库中匹配
  • 精确查询:根据精确词条值查找数据,一般是查找keyword,数值,日期,boolean等类型字段,精确查询不走倒排索引,会将整个文本插入到倒排索引库中
  • 地理查询:根据经纬度查询
  • 复合查询:复合查询可以将上述各种查询条件组合起来,合并查询条件

4.全文检索

match

介绍

match在匹配时会对所查找的关键词进行分词,然后按分词匹配查找

默认多个词是or关系,只要有一个词匹配就会查询出来

参数
  • query:指定匹配的值
  • operator:匹配条件类型
    • and:条件分词后都要匹配
    • or:条件分词后有一个匹配即可(默认)
  • minmum_should_match:最低匹配度,即条件在倒排索引中最低的匹配度,匹配几个词才行
示例
GET /[索引名称]/_search
{
    "query":{
        "match":{
            "字段名":{
                "query":"值",
                "operator":"and",
                "fuzziness": 2
                "minmum_should_match":2
            }
        }
    }
}

match_phrase

介绍

match_phrase查询分析文本并根据分析的文本创建一个短语查询。match_phrase会将检索关键词分词。match_phrase的分词结果必须在被检索字段的分词中都包含,而且顺序必须相同,而且默认必须都是连续的

参数
  • slop:可以跳过分词后的词语数量
示例
GET /[索引名称]/_search
{
    "query":{
        "match_phrase":{
            "address":{
                "query":"广州白云山",
                "slop":2
            }
        }
    }
}

multi_match

介绍

可以根据字段类型,决定是否使用分词查询,得分最高的在前面

就是一个值同时匹配多个字段

示例
GET /[索引名称]/_search
{
    "query":{
        "multi_match":{
            "query":"值",
            "fields":["字段1","字段2"]
        }
    }
}
注意

字段类型分词,将查询条件分词之后进行查询,如果该字段不分词就会将查询条件作为整体进行查询

query_string

介绍

允许我们在单个查询字符串中指定AND | OR | NOT条件,同时也和multi_match query一样,支持多字段搜索。和match类似,但是match需要指定字段名,query_string是在所有字段中搜索,范围更广泛

示例
// 不指定字段就是匹配所有字段

// 指定字段查询
GET /[index]/_search
{
    "query":{
        "query_string":{
            "default_field":"字段名",
            "query":"白云山 OR 橘子洲"
        }
    }
}
// 多字段查询
GET /[index]/_search
{
    "query":{
        "query_string":{
            "fields":["字段名1","字段名2"],
            "query":"张三 OR (广州 AND 王五)"
        }
    }
}
注意

查询字段分词就将查询条件分词查询,查询字段不分词将查询条件不分词查询

or and 啥的不要用小写

simple_query_string

介绍

类似Query String,但是会忽略错误的语法,同时只支持部分查询语法,不支持AND OR NOT,会当作字符串处理

特点
  • +代替AND
  • |代替OR
  • -代替NOT
示例
GET /[index]/_search
{
    "query":{
        "simple_query_string":{
            "fields":["字段名1","字段名2"],
            "query":"张三 | (广州 + 王五)",
            "default_operator":"AND" // 可以忽略和+使用一个即可
        }
    }
}

5.精确查询

term

介绍

Term用来使用关键词查询(精确匹配),还可以用来查询没有被进行分词的数据类型。Term是表达语意的最小单位,搜索和利用统计语言模型进行自然语言处理都需要处理Term

match在匹配时会对所查找的关键词进行分词,然后按分词匹配查找,而term会直接对关键词进行查找。一般模糊查找的时候,多用match,而精确查找时可以使用term

什么类型分词

在ES的Mapping Type 中 keyword , date ,integer, long , double , boolean ip 这些类型不分词,只有text类型分词

示例
GET /[索引名称]/_search
{
    "query":{
        "term":{
            "字段名":{
                "value":"值"
            }
        }
    }
}

GET /[索引名称]/_search
{
    "query":{
        //  避免算分,而且term可以利用缓存
        "constant_score":{
            "filter":{
                "term":{
                	// text是有子类型的,这样精确匹配就可以了
                    "address.keyword":"广州白云山公园"
                }
            }
        }
    }
}
注意

可以通过 Constant Score 将查询转换成一个 Filtering,避免算分,并利用缓存,提高性能

ids

介绍

指定多个ip匹配文档

示例
GET /[索引名称]/_search
{
  "query":{
    "ids":{
      "values":[1001,1002]
    }
  }
}

mget

介绍

批量查询根据id

示例
GET /[索引名称]/_mget
{
    "docs":[
        {"index":"索引名","_id":id值},
        {"index":"索引名","_id":id值}
    ]  
}
GET /[索引名称]/_mget
{
    "ids":["1","2"]
}

terms

暂时省略

prefix

介绍

它会对分词后的term进行前缀搜索

它不会分析要搜索字符串,传入的前缀就是想要查找的前缀

默认状态下,前缀查询不做相关度分数计算,它只是将所有匹配的文档返回,然后赋予所有相关分数值为1。它的行为更像是一个过滤器而不是查询。两者实际的区别就是过滤器是可以被缓存的,而前缀查询不行

原理

需要遍历所有倒排索引,并比较每个term是否已所指定的前缀开头

所以有性能问题

示例
GET /[索引名称]/_search
{
    "query":{
        "prefix":{
            "字段名":{
                "value":"值"
            }
        }
    }
}

wildcard

介绍

通配符查询:工作原理和prefix相同,只不过它不是只比较开头,它能支持更为复杂的匹配模式

示例
GET /[索引名称]/_search
{
    "query":{
        "wildcard":{
            "字段名":{
                "value":"*白*"
            }
        }
    }
}

range

介绍

范围查询

范围关键字
  • range:范围关键字
  • gte:大于等于
  • lte:小于等于
  • gt:大于
  • lt:小于
  • now:当前时间
示例
# 大于等于10小于等于20,gte大于等于,gt大于,lt小于,lte小于等于
GET /[索引名称]/_search
{
    "query":{
        "range":{
            "字段名":{
                "gte":10,
                "lte":20
            }
        }
    }
}
GET /[索引名称]/_search
{
    "query":{
        "range":{
            "date":{
                // 2年之前的数据
                "gte":"now-2y"
            }
        }
    }
}

fuzzy

介绍

在实际的搜索中,我们有时候会打错字,从而导致搜索不到。在Elasticsearch中,我们可以使用fuzziness属性来进行模糊查询,从而达到搜索有错别字的情形

参数
  • fuzziness:表示输入的关键字通过几次操作可以转变成为ES库里面的对应field的字段,默认是0不开启
  • prefix_length:表示限制输入关键字和ES对应查询field的内容开头的第n个字符必须完全匹配,不允许错别字匹配,默认值为0
示例
GET /es_db/_search
 {
 "query": {
 "fuzzy": {
 "address": {
 "value": "白运山",
 "fuzziness": 1
 }
 }
 }
 }

 GET /es_db/_search
 {
 "query": {
 "match": {
 "address": {
 "query": "广洲",
 "fuzziness": 1
 }
}
}
}
注意
  • fuzzy 模糊查询 最大模糊错误 必须在0-2之间
  • 搜索关键字长度为2,不允许存在模糊
  • 搜索关键字长度为3-5,允许1次模糊
  • 搜索关键字长度大于5,允许最多2次模糊

5.bool查询

介绍

一个bool查询,是一个或者多个查询子句的组合,总共包括4种子句,其中2种会影响算分,2种不影响算分

四种自句

  • must: 相当于&& ,必须匹配,贡献算分
  • should: 相当于|| ,选择性匹配,贡献算分
  • must_not: 相当于! ,必须不能匹配,不贡献算分
  • filter: 必须匹配,不贡献算分

两种Context

  • 在Elasticsearch中,有Query和 Filter两种不同的Context
  • Query Context: 相关性算分
  • Filter Context: 不需要算分 ,可以利用Cache,获得更好的性能

算分注意事项

如果多条查询子句被合并为一条复合查询语句,比如 bool查询,则每个查询子句计算得出的评分会被合并到总的相关性评分中

其他注意事项

  • 子查询可以任意顺序出现
  • 可以嵌套多个查询
  • 如果你的bool查询中,没有must条件,should中必须至少满足一条查询

语法

GET /[索引名称]/_search
{
    "query":{
        "bool":{
            "must":[
                {"term":{"city":"上海"}}
            ],
            "should":[
                {"term":{"brand":"皇冠假日"}},
                {"term":{"brand":"华美达"}}
            ],
            "must_not":[
                {"range":{"price":{"lte":500}}}
            ],
            "filter":[
                {"range":{"score":{"gte":45}}}
            ]
        }
    }
}
文章来源:https://blog.csdn.net/weixin_43891622/article/details/135823910
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。