自己做壁纸的网站,杭州网站建设外包公司,设计品牌有哪些,百度云怎么做网站空间DSL查询
Elasticsearch的查询可以分为两大类#xff1a; 叶子查询#xff08;Leaf query clauses#xff09;#xff1a;一般是在特定的字段里查询特定值#xff0c;属于简单查询#xff0c;很少单独使用。 复合查询#xff08;Compound query clauses#xff09; 叶子查询Leaf query clauses一般是在特定的字段里查询特定值属于简单查询很少单独使用。 复合查询Compound query clauses以逻辑方式组合多个叶子查询或者更改叶子查询的行为方式
语法示例
GET /{索引库名}/_search
{query: {查询类型: {// .. 查询条件}}
}
无条件查询的类型是match_all
GET /items/_search
{query: {match_all: {}}
}
获取到的结果 你会发现虽然是match_all但是响应结果中并不会包含索引库中的所有文档而是仅有10条。这是因为处于安全考虑elasticsearch设置了默认的查询页数。
叶子查询
叶子查询的类型也可以做进一步细分详情大家可以查看官方文档
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/query-dsl.html
这里列举一些常见的例如 全文检索查询Full Text Queries利用分词器对用户输入搜索条件先分词得到词条然后再利用倒排索引搜索词条。例如 match multi_match 精确查询Term-level queries不对用户输入搜索条件分词根据字段内容精确值匹配。但只能查找keyword、数值、日期、boolean类型的字段。例如 ids term range 地理坐标查询用于搜索地理位置搜索方式很多例如 geo_bounding_box按矩形搜索 geo_distance按点和半径搜索
全文检索查询
全文检索的种类也很多详情可以参考官方文档
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/full-text-queries.html
match匹配单个字段语法如下
GET /{索引库名}/_search
{query: {match: {字段名: 搜索条件}}
}
使用实例
GET /items/_search
{query: {match: {name: 手机}}
}
查询结果 multi_match匹配多个字段语法如下
GET /{索引库名}/_search
{query: {multi_match: {query: 搜索条件,fields: [字段1, 字段2]}}
}
实例我们搜索带华为二字的品牌与名字的商品
GET /items/_search
{query: {multi_match: {query: 华为,fields: [brand,name]}}
} 精确查询
推荐查找keyword、数值、日期、boolean类型的字段。
详情可以查看官方文档
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/term-level-queries.html
term查询(精确查询某个字段的相同值的文档)语法如下
GET /{索引库名}/_search
{query: {term: {字段名: {value: 搜索条件}}}
} 实例查询一个品牌为诺基亚的商品
GET /items/_search
{query: {term: {brand: {value: 诺基亚}}}
} range查询(处于某个字段范围内的文档)语法如下
GET /{索引库名}/_search
{query: {range: {字段名: {gte: {最小值},lte: {最大值}}}}
} 实例查询价格处于500-1000的商品由于数据库的存储单位为分所以我们查询时多加两个零
GET /items/_search
{query: {range: {price: {gte: 50000,lte: 100000}}}
} range是范围查询对于范围筛选的关键字有 gte大于等于 gt大于 lte小于等于 lt小于
复合查询
算分函数查询
采用的相关性打分算法是BM25算法公式如下 基本语法
function score 查询中包含四部分内容 原始查询条件query部分基于这个条件搜索文档并且基于BM25算法给文档打分原始算分query score) 过滤条件filter部分符合该条件的文档才会重新算分 算分函数符合filter条件的文档要根据这个函数做运算得到的函数算分function score有四种函数 weight函数结果是常量 field_value_factor以文档中的某个字段值作为函数结果 random_score以随机数作为函数结果 script_score自定义算分函数算法 运算模式算分函数的结果、原始查询的相关性算分两者之间的运算方式包括 multiply相乘 replace用function score替换query score 其它例如sum、avg、max、min
function score的运行流程如下 1根据原始条件查询搜索文档并且计算相关性算分称为原始算分query score 2根据过滤条件过滤文档 3符合过滤条件的文档基于算分函数运算得到函数算分function score 4将原始算分query score和函数算分function score基于运算模式做运算得到最终结果作为相关性算分。
因此其中的关键点是 过滤条件决定哪些文档的算分被修改 算分函数决定函数算分的算法 运算模式决定最终算分结果
实例给IPhone这个品牌的手机算分提高十倍分析如下 过滤条件品牌必须为IPhone 算分函数常量weight值为10 算分模式相乘multiply
GET /hotel/_search
{query: {function_score: {query: { .... }, // 原始查询可以是任意条件functions: [ // 算分函数{filter: { // 满足的条件品牌必须是Iphoneterm: {brand: Iphone}},weight: 10 // 算分权重为2}],boost_mode: multipy // 加权模式求乘积}}
}
bool查询
bool查询即布尔查询。就是利用逻辑运算来组合一个或多个查询子句的组合。bool查询支持的逻辑运算有 must必须匹配每个子查询类似“与” should选择性匹配子查询类似“或” must_not必须不匹配不参与算分类似“非” filter必须匹配不参与算分
bool查询基本语法
GET /items/_search
{query: {bool: {must: [{match: {name: 手机}}],should: [{term: {brand: { value: vivo }}},{term: {brand: { value: 小米 }}}],must_not: [{range: {price: {gte: 2500}}}],filter: [{range: {price: {lte: 1000}}}]}}
} 出于性能考虑与搜索关键字无关的查询尽量采用must_not或filter逻辑运算避免参与相关性算分 我们要搜索手机但品牌必须是华为价格必须是900~1599那么可以这样写
GET /items/_search
{query: {bool: {must: [{match: {name: 手机}}],filter: [{term: {brand: { value: 华为 }}},{range: {price: {gte: 90000, lt: 159900}}}]}}
} 排序
elasticsearch默认是根据相关度算分_score来排序但是也支持自定义方式对搜索结果排序。不过分词字段无法排序能参与排序字段类型有keyword类型、数值类型、地理坐标类型、日期类型等。
详细说明可以参考官方文档
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/sort-search-results.html 语法如下
GET /indexName/_search
{query: {match_all: {}},sort: [{排序字段: {order: 排序方式asc和desc}}]
}
实例按照商品价格进行排序
GET /items/_search
{query: {match_all: {}},sort: [{price: {order: desc}}]
}
可以看到商品价格呈现降序 分页
elasticsearch 默认情况下只返回top10的数据。而如果要查询更多数据就需要修改分页参数了。
基础分页
elasticsearch中通过修改from、size参数来控制要返回的分页结果 from从第几个文档开始 size总共查询几个文档
类似于mysql中的limit ?, ?
官方文档如下
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/paginate-search-results.html
基本语法:
GET /items/_search
{query: {match_all: {}},from: 0, // 分页开始的位置默认为0size: 10, // 每页文档数量默认10sort: [{price: {order: desc}}]
}
深度分页
针对深度分页elasticsearch提供了两种解决方案 search after分页时需要排序原理是从上一次的排序值开始查询下一页数据。官方推荐使用的方式。 scroll原理将排序后的文档id形成快照保存下来基于快照做分页。官方已经不推荐使用。
详情见文档
https://www.elastic.co/guide/en/elasticsearch/reference/7.12/paginate-search-results.html
总结
大多数情况下我们采用普通分页就可以了。查看百度、京东等网站会发现其分页都有限制。例如百度最多支持77页每页不足20条。京东最多100页每页最多60条。
因此一般我们采用限制分页深度的方式即可无需实现深度分页。 高亮 高亮词条都被加了em标签 em标签都添加了红色样式
高亮标签肯定是由服务端提供数据的时候已经加上的。
基本语法如下
GET /{索引库名}/_search
{query: {match: {搜索字段: 搜索关键字}},highlight: {fields: {高亮字段名称: {pre_tags: em,post_tags: /em}}}
} 注意 搜索必须有查询条件而且是全文检索类型的查询条件例如match 参与高亮的字段必须是text类型的字段 默认情况下参与高亮的字段要与搜索字段一致除非添加required_field_matchfalse
实例我们将华为二字高亮显示
GET /items/_search
{query: {match: {name: 华为}},highlight: {fields: {name: {pre_tags: em,post_tags: /em}}}
} 总结
查询的DSL是一个大的JSON对象包含下列属性 query查询条件 from和size分页条件 sort排序条件 highlight高亮条件
数据聚合
Bucket聚合
其实就是以分类category字段对数据分组。category值一样的放在同一组属于Bucket聚合中的Term聚合。
基本语法如下
GET /items/_search
{size: 0, aggs: {category_agg: {terms: {field: category,size: 20}}}
}
语法说明 size设置size为0就是每页查0条则结果中就不包含文档只包含聚合 aggs定义聚合 category_agg聚合名称自定义但不能重复 terms聚合的类型按分类聚合所以用term field参与聚合的字段名称 size希望返回的聚合结果的最大数量
带条件聚合
我们需要从需求中分析出搜索查询的条件和聚合的目标 搜索查询条件 价格高于3000 必须是手机 聚合目标统计的是品牌肯定是对brand字段做term聚合
语法如下
GET /items/_search
{query: {bool: {filter: [{term: {category: 手机}},{range: {price: {gte: 300000}}}]}}, size: 0, aggs: {brand_agg: {terms: {field: brand,size: 20}}}
}
Metric聚合
语法如下
GET /items/_search
{query: {bool: {filter: [{term: {category: 手机}},{range: {price: {gte: 300000}}}]}}, size: 0, aggs: {brand_agg: {terms: {field: brand,size: 20},aggs: {stats_meric: {stats: {field: price}}}}}
}
可以看到我们在brand_agg聚合的内部我们新加了一个aggs参数。这个聚合就是brand_agg的子聚合会对brand_agg形成的每个桶中的文档分别统计。 stats_meric聚合名称 stats聚合类型stats是metric聚合的一种 field聚合字段这里选择price统计价格
由于stats是对brand_agg形成的每个品牌桶内文档分别做统计因此每个品牌都会统计出自己的价格最小、最大、平均值。
总结
aggs代表聚合与query同级此时query的作用是 限定聚合的的文档范围
聚合必须的三要素 聚合名称 聚合类型 聚合字段
聚合可配置属性有 size指定聚合结果数量 order指定聚合结果排序方式 field指定聚合字段