文档索引
ES 7.4 版本 Pinned Query 新特性介绍
ES 8.11 当前版本 Pinned Query 文档
ES 掘金作者 Pinned Query 介绍
特性简介
Pinned query 特性在 ES7.4 版本中被引入, 其主要作用是将特定id的文档固定在搜索结果的最前端。
示例请求:
GET /_search
{
"query": {
"pinned": {
"ids": [ "1", "4", "100" ],
"organic": {
"match": {
"description": "iphone"
}
}
}
}
}
参数:
- ids 需要固定在最前方的文档对应的_id,英文文档中有一些微妙的描述 ,后面再统一解释。
(Optional, array) Document IDs listed in the order they are to appear in results. Required if docs is not specified.
- docs (可选,数组)按文档在结果中的显示顺序列出的文档。如果未指定ID,则为必需项。该选项最早在7.15版本的文档中出现,早期的ES版本没有加入该选项(测试版本7.4.2)参数包含:
_index和_id,可以用于跨多个索引的检索。官方示例如下:
GET /_search
{
"query": {
"pinned": {
"docs": [
{
"_index": "my-index-000001",
"_id": "1"
},
{
"_index": "my-index-000001",
"_id": "4"
},
{
"_index": "my-index-000002",
"_id": "100"
}
],
"organic": {
"match": {
"description": "iphone"
}
}
}
}
}
- organic 用于对排名在“固定”文档之下的文档进行排名的任何查询选项。英文翻译非常拗口,可以理解为除固定文档外需要执行的查询。
使用测试
下面是一些关于Pinned Query 查询的使用测试情况,版本基于 ES 7.4.2
创建文档如下:
PUT /test-index
{
"mappings": {
"properties": {
"num": {
"type": "integer"
}
}
}
}
PUT /test-index/_doc/1
{
"num":1
}
PUT /test-index/_doc/2
{
"num":2
}
PUT /test-index/_doc/3
{
"num":3
}
PUT /test-index/_doc/4
{
"num":4
}
测试1:ids参数
先说测试结果:
- 测试是否必须:是,参数一定要存在。(高版本和 docs参数 选其一)
- 测试是否可为空:否,参数不能为空。
- 测试是否可传单个参数:是,参数可以以单个形式传递。
- 测试是否可传空数组:是,空数组不会产生报错。
- 测试
ids文档号不在索引中的情况:不会报错,不会影响排序。 - 测试
ids文档固定的文档数上限:100,超过100将报错。
// 测试是否必须
GET /test-index/_search
{
"query": {
"pinned" : {
"organic" : {
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
// 测试是否可为空
GET /test-index/_search
{
"query": {
"pinned" : {
"ids" : "",
"organic" : {
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
// 测试是否可传单个参数
GET /test-index/_search
{
"query": {
"pinned" : {
"ids" : "1",
"organic" : {
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
// 测试是否可为空数组
GET /test-index/_search
{
"query": {
"pinned" : {
"ids" : [],
"organic" : {
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
// 测试 ids 文档号不在索引中的情况
GET /test-index/_search
{
"query": {
"pinned" : {
"ids":[5],
"organic" : {
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
// 测试 ids 固定文档上限
GET /test-index/_search
{
"query": {
"pinned" : {
"ids":["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16","17","18","19","20","21","22","23","24","25","26","27","28","29","30","31","32","33","34","35","36","37","38","39","40","41","42","43","44","45","46","47","48","49","50","51","52","53","54","55","56","57","58","59","60","61","62","63","64","65","66","67","68","69","70","71","72","73","74","75","76","77","78","79","80","81","82","83","84","85","86","87","88","89","90","91","92","93","94","95","96","97","98","99","100","101"],
"organic" : {
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
测试2:organic 参数
测试结果:
- 测试是否必须:是,不传
organic参数会直接报错,也不能空对象。 - 测试
bool查询:可以正常编写复杂查询。
// 是否必须
GET /test-index/_search
{
"query": {
"pinned" : {
"ids" : "1"
}
}
}
// bool 查询
GET /test-index/_search
{
"query": {
"pinned" : {
"ids" : "1",
"organic" : {
"bool" : {
"must" :{
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
}
}
测试3:排序
测试结果:
- 测试多个
ids参数排序:多个参数排序取决于传入的顺序。 - 测试添加
sort排序:外层sort的排序会影响pinned query,排序将重排,排序结果将取决于sort的结果,固定效果将失效。
// 多个 ids 参数排序
GET /test-index/_search
{
"query": {
"pinned" : {
"ids":[2,3],
"organic" : {
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
// 添加 sort 排序
GET /test-index/_search
{
"sort": [
{
"num": {
"order": "desc"
}
}
],
"query": {
"pinned" : {
"ids":[2,3],
"organic" : {
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
注:由于sort排序将影响 pinned query,pinned query会提高固定文档的得分,可以考虑将_score纳入sort排序中进行调整。
参考:
GET /test-index/_search
{
"sort": [
{
"_score": {
"order": "desc"
}
},
{
"num": {
"order": "desc"
}
}
],
"query": {
"pinned" : {
"ids":[2,3],
"organic" : {
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
// 运行结果
// 2,3 文档将固定在前面,其他文档将按num大小排序
测试4: 分页
测试结果:
- 测试分页首页数量受
pinned query影响: 不受影响,size指定多少就是多少。 - 测试下一页是否会出现固定文档:不会出现固定文档,固定文档只会出现在首页,正确来说是按得分顺序排序下来。
// 测试数量
GET /test-index/_search
{
"size":2,
"from":0,
"query": {
"pinned" : {
"ids":[1],
"organic" : {
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
// 测试下一页是否会出现固定文档
GET /test-index/_search
{
"size":2,
"from":2,
"query": {
"pinned" : {
"ids":[1],
"organic" : {
"range" : {
"num" : {
"gte" : 0
}
}
}
}
}
}
如有错漏,欢迎评论指正。