百度翻译api wordpress,seo黑帽2022,wordpress桌面宠物,有道搜索引擎入口文章目录 ES高级查询Query DSLmatch_all返回源数据_source返回指定条数size分页查询fromsize指定字段排序sort 术语级别查询term query术语查询terms query多术语查询range query范围查询exists queryids queryprefix query前缀查询wildcard query通配符查询fuzzy query模… 文章目录 ES高级查询Query DSLmatch_all返回源数据_source返回指定条数size分页查询fromsize指定字段排序sort 术语级别查询term query术语查询terms query多术语查询range query范围查询exists queryids queryprefix query前缀查询wildcard query通配符查询fuzzy query模糊查询 全文检索match query匹配查询multi_match query 多字段查询match_phrase query短语查询query_string querysimple_query_string bool query布尔查询highlight高亮基本使用自定义高亮标签多字段高亮 ES高级查询Query DSL
ES中提供了一种强大的检索数据方式,这种检索方式称之为Query DSLDomain Specified Language 领域专用语言 ,
Query DSL是利用Rest API传递JSON格式的请求体(RequestBody)数据与ES进行交互这种方式的丰富查询语法让ES检索变得更强大更简洁。
官网
标准格式如下
GET /索引名/_doc/_search {JOSN请求体}# 也可以省略_doc 简写成下面这种方式
GET /索引名//_search {JOSN请求体}案例
# 无条件查询默认返回10条数据
GET /sys_user/_search
{query: {match_all: {}}
}案例数据生成接下来的案例很多都是操作改索引
# 删除现有索引
DELETE /sys_user# 重新创建索引 指定ik分词器
PUT /sys_user
{settings : {index : {analysis.analyzer.default.type: ik_max_word}}
}# 创建文档,指定id
PUT /sys_user/_doc/1
{
name: 张三,
sex: 1,
age: 25,
address: 广州天河公园,
remark: java developer
}
PUT /sys_user/_doc/2
{
name: 李四,
sex: 1,
age: 28,
address: 广州荔湾大厦,
remark: java assistant
}PUT /sys_user/_doc/3
{
name: 王五,
sex: 0,
age: 26,
address: 广州白云山公园,
remark: php developer
}PUT /sys_user/_doc/4
{
name: 赵六,
sex: 0,
age: 22,
address: 长沙橘子洲,
remark: python assistant
}PUT /sys_user/_doc/5
{
name: 张龙,
sex: 0,
age: 19,
address: 长沙麓谷企业广场,
remark: java architect assistant
} PUT /sys_user/_doc/6
{
name: 赵虎,
sex: 1,
age: 32,
address: 长沙麓谷兴工国际产业园,
remark: java architect
} PUT /sys_user/_doc/7
{
name: 李虎,
sex: 1,
age: 32,
address: 广州番禺节能科技园,
remark: java architect
}PUT /sys_user/_doc/8
{
name: 张星,
sex: 1,
age: 32,
address: 武汉东湖高新区未来智汇城,
remark: golang developer
}match_all
使用match_all匹配所有文档默认只会返回10条数据。
原因_search查询默认采用的是分页查询每页记录数size的默认值为10。如果想显示更多数据指定size
# 无条件查询_search默认返回10条数据
GET /sys_user/_search# 等价于
GET /sys_user/_search
{query: {match_all: {}}
}返回源数据_source
_source关键字是一个数组在数组中指定用来指定暂时哪些字段类似于Mysql的select 字段 from table 或MongoDB中的 $project映射
# _source关键字的相关操作
# 返回指定字段
GET /sys_user/_search
{query: {match_all: {}},_source: [name,age]
}#不查看源数据仅查看元字段
GET /sys_user/_search
{query: {match_all: {}},_source: false
}# 只看以a开头的字段
GET /sys_user/_search
{query: {match_all: {}},_source: a*
}返回指定条数size
size 关键字: 指定查询结果中返回指定条数。 默认返回值10条
# 通过size关键字指定返回结果数
GET /sys_user/_search
{query: {match_all: {}},size: 20
}分页查询fromsize
size显示应该返回的结果数量默认是 10
from显示应该跳过的初始结果数量默认是 0
from 关键字用来指定起始返回位置和size关键字连用可实现分页效果
# 通过from size关键字实现分页
# 跳过前面5个文档共显示两个文档
GET /sys_user/_search
{query: {match_all: {}},from: 5, size: 2
}指定字段排序sort
注意sort排序会让 _score相关性得分失效
# 使用sort关键字按age字段降序 排序
GET /sys_user/_search
{query: {match_all: {}},sort: [{age: {order: desc}}]
}# sort排序 from size分页
GET /sys_user/_search
{query: {match_all: {}},sort: [{age: {order: desc}}],from: 5,size: 3
}术语级别查询
术语级别查询Term-Level Queries指的是搜索内容不经过文本分析直接用于文本匹配
搜索的对象大多是索引的非text类型字段。 term query术语查询
Term查询对输入不做分词。会将输入作为一个整体在倒排索引中查找准确的词项
术语查询直接返回包含搜索内容的文档常用来查询索引中某个类型为keyword的文本字段类似于SQL的“”查询使用十分普遍。
注意最好不要在term查询的字段中使用text字段因为text字段会被分词这样做既没有意义还很有可能什么也查不到。
# 对bool日期数字结构化的文本可以利用term做精确匹配
# term 精确匹配
GET /sys_user/_search
{query: {term: {age: {value: 25}}}
}# 思考 查询广州白云是否有数据为什么
# 没有数据因为address是text类型索引数据时会创建倒排索引而直接用 term 广州白云这个词 倒排索引中不存在所以查询不到数据
GET /sys_user/_search
{query: {term: {address: {value: 广州白云}}}
}# 采用term精确查询, 查询字段映射类型为keyword
# 能查询都数据因为address字段是类型为text 子类型为keyword会创建一个完整address字段内容在倒排索引中
GET /sys_user/_search
{query: {term: {address.keyword: {value: 广州白云山公园}}}
}在ES中Term查询对输入不做分词。会将输入作为一个整体在倒排索引中查找准确的词项并且使用相关度算分公式为每个包含该词项的文档进行相关度算分。
可以通过 constant_score 将查询转换成一个 Filtering避免算分并利用缓存提高性能。
将Query 转成 Filter忽略TF-IDF计算避免相关性算分的开销Filter可以有效利用缓存
# 使用constant_score filter 避免相关性算分
GET /sys_user/_search
{query: {constant_score: {filter: {term: {address.keyword: 广州白云山公园}}}}
}term处理多值字段时term查询是包含不是等于。
POST /employee/_bulk
{index:{_id:1}}
{name:小明,interest:[跑步,篮球]}
{index:{_id:2}}
{name:小红,interest:[跳舞,画画]}
{index:{_id:3}}
{name:小丽,interest:[跳舞,唱歌,跑步]}terms query多术语查询
terms 用于指定字段上匹配多个词项这里会精确匹配指定字段中包含的任何一个词项
# trems 多术语匹配
GET /sys_user/_search
{query: {terms: {remark.keyword: [java developer,java assistant]}}}
}range query范围查询
关键字
range 范围关键字gte 大于等于lte 小于等于gt 大于lt 小于now 当前时间 # 查询age在[18,25]之间的文档并对结果做一个降序排序
GET /sys_user/_search
{query: {range: {age: {gte: 18,lte: 25}}}, sort: [{age: {order: desc}}]
}日期范围的比较 可以使用now表示当前时间
# 日期范围的比较
PUT /product/_bulk
{index: {_id: 1}}
{productId: XHDK-1293,price: 100,date: 2022-01-01}
{index: {_id: 2}}
{productId: XHDK-3566,price: 200,date: 2023-01-01}# 当前时间 - 2年 当然你也可以直接写gte: 2022-08-12
GET /product/_search
{query: {range: {date: {gte: now-2y}}}
}exists query
使用exists关键字查询查询文档中所有存在该字段的文档
字段不存在 和 字段值为null的文档都查询不出来
# 查询所有存在name字段的文档数据
GET /sys_user/_search
{query: {exists: {field: name}}
}# 索引一个文档没有name字段
POST /sys_user/_doc
{sex: 1,age: 25,address: 广州天河公园111,remark: java developer111
}# 索引一个文档name字段的值为null
POST /sys_user/_doc
{name: null,sex: 1,age: 25,address: 广州天河公园222,remark: java developer222
}# 索引一个文档name字段的值为
POST /sys_user/_doc
{name: ,sex: 1,age: 25,address: 广州天河公园333,remark: java developer333
}# 最终只能查询到 name字段的值为 的文档 name字段不存在 和 name值为null的文档都查询不出来
GET /sys_user/_search
{query: {exists: {field: name}}
}ids query
ids关键字值为数组类型可以根据一组id查询文档数据
# 使用ids关键字查询一组id对应的文档
GET /sys_user/_search
{query: {ids: {values: [1,2,3]}}
}prefix query前缀查询
直接根据传入的前缀去倒排索引中进行匹配判断倒排索引中的每个term是否以所指定的前缀开头。它不会分析要搜索字符串传入的前缀就是想要查找的前缀
默认状态下前缀查询不做相关性分数计算它只是将所有匹配的文档返回然后赋予所有相关分数值为1。它的行为更像是一个过滤器而不是查询。两者实际的区别就是过滤器是可以被缓存的而前缀查询不行。
# 使用prefilx前缀匹配查询
GET /sys_user/_search
{query: {prefix: {address: {value: 广州}}}
}wildcard query通配符查询
工作原理和prefix相同只不过它不是只比较开头它能支持更为复杂的匹配模式。
# 使用wildcard通配符匹配
GET /sys_user/_search
{query: {wildcard: {address: {value: *白*}}}
}fuzzy query模糊查询
使用fuzziness属性来进行模糊查询从而达到搜索有错别字的情形。
fuzzy 查询会用到两个很重要的参数fuzzinessprefix_length fuzziness 对输入的关键字进行几次操作可以和倒排索引中的term词匹配。 新增一个字符删除一个字符修改一个字符每次操作可以记做编辑距离为1; 该参数默认值为0即不开启模糊查询; fuzzy 模糊查询 最大模糊错误必须在0-2之间 prefix_length 输入的关键字前面几个字符必须要和倒排索引的term词匹配关键字前面几个字符不允许写错 默认值为0
# 使用fuzzy关键字进行模糊查询
# 允许一个错别字但是第一个字不能是错别字
GET /sys_user/_search
{query: {fuzzy: {address: {value: 白晕山,fuzziness: 1,prefix_length: 1}}}
}全文检索
全文检索查询旨在基于相关性搜索和匹配文本数据。
这些查询会对输入的文本进行分析将其拆分为词项单个单词并执行诸如分词、词干处理和标准化等操作。
以相关性为基础进行搜索和匹配。全文检索查询使用相关性算法来确定文档与查询的匹配程度并按照相关性进行排序。相关性可以基于词项的频率、权重和其他因素来计算。 match query匹配查询
match在匹配时会对所查找的关键词进行分词然后按分词匹配查找。
match支持以下参数 query : 指定匹配的值 operator : 匹配条件类型 and : 条件分词后都要匹配or : 条件分词后有一个匹配即可(默认) minmum_should_match : 最低匹配度即条件在倒排索引中最低的匹配度
# 下面两种写法一样两种写法都是operator分词后or的效果
GET /sys_user/_search
{query: {match: {address: 广州白云山}}
}# 如果只有关键词需要指定那么match关键词下的query参数就可以省略
GET /sys_user/_search
{query: {match: {address: {query: 广州白云山}}}
}# 分词后 and的结果
GET /sys_user/_search
{query: {match: {address: {query: 广州白云山,operator: and}}}
}# 如果分词后是or操作我们也可以添加minmum_should_match 来指定最低匹配度
# 至少要匹配两个分词
GET /sys_user/_search
{query: {match: {address: {query: 广州白云山公园,operator: or,minimum_should_match: 2}}}
}对于match查询其底层逻辑的概述
分词首先输入的查询文本会被分词器进行分词。分词器会将文本拆分成一个个词项terms如单词、短语或特定字符。分词器通常根据特定的语言规则和配置进行操作。倒排索引ES使用倒排索引来加速搜索过程。倒排索引是一种数据结构它将词项映射到包含这些词项的文档。每个词项都有一个对应的倒排列表其中包含了包含该词项的所有文档的引用。匹配计算一旦查询被分词ES将根据查询的类型和参数计算文档与查询的匹配度。对于match查询ES将比较查询的词项与倒排索引中的词项并计算文档的相关性得分。相关性得分衡量了文档与查询的匹配程度。结果返回根据相关性得分ES将返回最匹配的文档作为搜索结果。搜索结果通常按照相关性得分进行排序以便最相关的文档排在前面。 multi_match query 多字段查询
让查询关键词在文档内的多个字段中进行查询
# 使用multi_match让输入的关键词在多个字段中进行查找匹配
# 这其中也有 operator minimum_should_match 这些参数
GET /sys_user/_search
{query: {multi_match: {query: 长沙赵六,fields: [name, address],operator: or,minimum_should_match: 1}}
}match_phrase query短语查询
对搜索文本进行分词再去倒排索引找每个分词并要求分词相邻。可以通过slop参数设置允许分词之间出现的最大间隔距离
我们先来使用分词器来看看一个文本是如何分词的
GET _analyze
{analyzer: ik_max_word,text: 广州白云山
}那么我们现在输入文本广州白云山应该是能查询到数据因为这两个分词是相邻的如果输入文本广州白云应该是查询不到数据因为这两个分词是不相邻的
# 能查询到数据因为广州 白云山 这两个分词是相邻的
GET /sys_user/_search
{query: {match_phrase: {address: 广州白云山}}
}# 查询不到数据因为 广州 白云 这两个分词是不相邻
GET /sys_user/_search
{query: {match_phrase: {address: 广州白云}}
}# slop参数设置允许分词之间出现的最大间隔距离
GET /sys_user/_search
{query: {match_phrase: {address: {query: 广州白云,slop: 2}}}
}query_string query
对输入的文本在文档中所有字段进行匹配搜索
允许我们在单个查询字符串中指定AND | OR | NOT条件必须大写
它也支持单字段查询和多字段查询只不过这些功能我们通过match、multi_match也能实现
# 未指定字段查询查询文档中的所有字段的值
# AND必须大写 文档中必须包含这两个分词才能查询出来
GET /sys_user/_search
{query: {query_string: {query: 赵六 AND 橘子洲}}
}# 指定单字段 添加default_field参数
GET /sys_user/_search
{query: {query_string: {default_field: address, query: 赵六 OR 橘子洲}}
}# 指定多字段 添加
GET /sys_user/_search
{query: {query_string: {fields: [name, address], query: 张三 OR (赵六 AND 橘子洲)}}
}simple_query_string
类似于query_string 但是会忽略错误的语法同时只支持部分查询语法不支持AND OR NOT 如果存在AND这些会当作普通字符串处理。
支持部分逻辑
代替AND|代替OR-代替NOT
# simple_query_string 默认的operator是OR
GET /sys_user/_search
{query: {simple_query_string: {fields: [name,address],query: 广州公园,default_operator: AND}}
}GET /sys_user/_search
{query: {simple_query_string: {fields: [name,address],query: 广州 公园}}
}bool query布尔查询 搜索上下文query context 需计算每个文档与搜索条件相关性得分有一定性能开销带文本分析的全文检索查询语句适合放在搜索上下文中 过滤上下文filter context 只判断搜索条件跟文档是否匹配不计算相关性得分。可以使用缓存加快响应速度术语级别查询是否放在过滤上下文中 类型说明must可包含多个查询条件每个条件均满足的文档才能被搜索到每次查询需要计算相关度得分属于搜索上下文should可包含多个查询条件不存在must和fiter条件时至少要满足多个查询条件中的一个文档才能被搜索到否则需满足的条件数量不受限制,匹配到的查询越多相关度越高也属于搜索上下文filter可包含多个过滤条件每个条件均满足的文档才能被搜索到每个过滤条件不计算相关度得分结果在一定条件下会被缓存 属于过滤上下文must_not可包含多个过滤条件每个条件均不满足的文档才能被搜索到每个过滤条件不计算相关度得分结果在一定条件下会被缓存 属于过滤上下文 案例
生成案例数据
PUT /books
{settings: {number_of_replicas: 1,number_of_shards: 1},mappings: {properties: {id: {type: long},title: {type: text,analyzer: ik_max_word},language: {type: keyword},author: {type: keyword},price: {type: double},publish_time: {type: date,format: yyy-MM-dd},description: {type: text,analyzer: ik_max_word}}}
}POST /_bulk
{index:{_index:books,_id:1}}
{id:1, title:Java编程思想, language:java, author:Bruce Eckel, price:70.20, publish_time:2007-10-01, description:Java学习必读经典殿堂级著作赢得了全球程序员的广泛赞誉。}
{index:{_index:books,_id:2}}
{id:2,title:Java程序性能优化,language:java,author:葛一鸣,price:46.5,publish_time:2012-08-01,description:让你的Java程序更快、更稳定。深入剖析软件设计层面、代码层面、JVM虚拟机层面的优化方法}
{index:{_index:books,_id:3}}
{id:3,title:Python科学计算,language:python,author:张若愚,price:81.4,publish_time:2016-05-01,description:零基础学python光盘中作者独家整合开发winPython运行环境涵盖了Python各个扩展库}
{index:{_index:books,_id:4}}
{id:4, title:Python基础教程, language:python, author:Helant, price:54.50, publish_time:2014-03-01, description:经典的Python入门教程层次鲜明结构严谨内容翔实}
{index:{_index:books,_id:5}}
{id:5,title:JavaScript高级程序设计,language:javascript,author:Nicholas C. Zakas,price:66.4,publish_time:2012-10-01,description:JavaScript技术经典名著}bool 查询案例
# 使用must类型需满足所有查询条件属于搜索上下文
GET /books/_search
{query: {bool: {must: [{match: {title: Java编程}},{match: {description: 性能优化}}]}}
}# 使用 should 满足任意一个查询条件即可
# 通过 minimum_should_match 参数指定需要满足条件的个数
GET /books/_search
{query: {bool: {should: [{match: {title: java编程}},{match: {description: 性能优化}}],minimum_should_match: 1}}
}# 使用 filter 需满足所有查询条件
GET /books/_search
{query: {bool: {filter: [{range: {price: {gte: 20,lte: 100}}},{term: {language: java}}]}}
}highlight高亮
highlight 关键字: 可以让符合条件的文档中的关键词高亮。
highlight相关属性
pre_tags 前缀标签post_tags 后缀标签tags_schema 设置为styled可以使用内置高亮样式require_field_match 多字段高亮需要设置为false 基本使用
示例数据
#指定ik分词器
PUT /products
{settings : {index : {analysis.analyzer.default.type: ik_max_word}}
}PUT /products/_doc/1
{proId : 2,name : 牛仔男外套,desc : 牛仔外套男装春季衣服男春装夹克修身休闲男生潮牌工装潮流头号青年春秋棒球服男 7705浅蓝常规 XL,timestamp : 1576313264451,createTime : 2019-12-13 12:56:56
}PUT /products/_doc/2
{proId : 6,name : HLA海澜之家牛仔裤男,desc : HLA海澜之家牛仔裤男2019时尚有型舒适HKNAD3E109A 牛仔蓝(A9)175/82A(32),timestamp : 1576314265571,createTime : 2019-12-18 15:56:56
}测试
GET /products/_search
{query: {term: {name: {value: 牛仔}}},highlight: {fields: {*: {}}}
}自定义高亮标签
可以在highlight中使用pre_tags和post_tags
GET /products/_search
{query: {multi_match: {query: 牛仔,fields: [name,desc]}},highlight: {pre_tags: [span stylecolor:red], post_tags: [/span], fields: {*: {}}}
}多字段高亮
之前的案例中都是查询匹配哪些字段highlight高亮标签中才有这些字段数据。我们也可以指定多字段都可以有高亮数据
使用多字段高亮就需要把require_field_match 参数的值设置为false
# 多字段高亮
# require_field_match属性设置为false 在fields中指定多个字段
GET /products/_search
{query: {match: {name: 牛仔}},highlight: {pre_tags: [span stylecolor:red], post_tags: [/span], require_field_match: false, fields: {name: {},desc: {}}}
}