ElasticSearch 7 学习(13)高级搜索

索引别名的使用

在开发中,随着业务需求的迭代,较老的业务逻辑就要面临更新甚至是重构,而对于es来说,为了适应新的业务逻辑,可能就要对原有的索引做一些修改,比如对某些字段做调整,甚至是重建索引。而做这些操作的时候,可能会对业务造成影响,甚至是停机调整等问题。由此,es提供了索引别名来解决这些问题。索引别名就像一个快捷方式或是软连接,可以指向一个或多个索引,也可以给任意一个需要索引名的API来使用。别名的应用为程序提供了极大的灵活性。

查询别名 GET请求

  • 请求
localhost:9200/nba/_alias // 查询nba别名
localhost:9200/_aliases  // 查询所有别名
  • 响应
{
  // 语义: 查看所有别名
    "nba": {
        "aliases": {}
    },
    ".kibana_task_manager": {
        "aliases": {}
    },
    ".kibana_1": {
        "aliases": {
            ".kibana": {}
        }
    }
}

新增别名 POST请求

  • 请求
localhost:9200/_aliases
  • 请求体
{
  // 语义: nba 新建别名nba_v1.0
  "actions": [
    {
      "add": {
        "index": "nba",
        "alias": "nba_v1.0"
      }
    }
  ]
}
  • 响应
{
    "acknowledged": true
}

删除别名 POST请求

  • 请求
localhost:9200/_aliases
  • 请求体
{
  // 语义: 删除nba的nba_v1.0别名
  "actions": [
    {
      "remove": {
        "index": "nba",
        "alias": "nba_v1.0"
      }
    }
  ]
}
  • 响应
{
    "acknowledged": true
}

重命名别名 POST请求

  • 请求
localhost:9200/_aliases
  • 请求体
{
  // 先删除nba_v1.0 别名 在新增 nba_v2.0别名,即是重命名
  "actions": [
    {
      "remove": {
        "index": "nba",
        "alias": "nba_v1.0"
      }
    },
    {
      "add": {
        "index": "nba",
        "alias": "nba_v2.0"
      }
    }
  ]
}
  • 响应
{
    "acknowledged": true
}

通过别名获取索引 GET请求

  • 请求
localhost:9200/nba_v2.0
  • 响应
{
    "nba": {
        "aliases": {
            "nba_v2.0": {}
        },
        "mappings": {
            "properties": {
                "age": {
                    "type": "integer"
                },
                "birthDay": {
                    "type": "date"
                },
                "birthDayStr": {
                    "type": "keyword"
                },
                "code": {
                    "type": "text"
                },
                "country": {
                    "type": "text"
                },
                "countryEn": {
                    "type": "text"
                },
                "displayAffiliation": {
                    "type": "text"
                },
                "displayName": {
                    "type": "text"
                },
                "displayNameEn": {
                    "type": "text"
                },
                "draft": {
                    "type": "long"
                },
                "heightValue": {
                    "type": "float"
                },
                "jerseyNo": {
                    "type": "text"
                },
                "playYear": {
                    "type": "long"
                },
                "playerId": {
                    "type": "keyword"
                },
                "position": {
                    "type": "text"
                },
                "schoolType": {
                    "type": "text"
                },
                "teamCity": {
                    "type": "text"
                },
                "teamCityEn": {
                    "type": "text"
                },
                "teamConference": {
                    "type": "keyword"
                },
                "teamConferenceEn": {
                    "type": "keyword"
                },
                "teamName": {
                    "type": "keyword"
                },
                "teamNameEn": {
                    "type": "keyword"
                },
                "weight": {
                    "type": "text"
                }
            }
        },
        "settings": {
            "index": {
                "creation_date": "1573300240575",
                "number_of_shards": "1",
                "number_of_replicas": "1",
                "uuid": "X7FLu-8sRcijAYKUkgBZQQ",
                "version": {
                    "created": "7020199"
                },
                "provided_name": "nba"
            }
        }
    }
}

通过别名写索引 POST请求

当别名指定了一个索引,则可以做写的操作

  • 请求
localhost:9200/nba_v2.0/_doc/566
  • 请求体
{
    // 语义: 通过别名nba_v2.0 修改id为566的球员
    "countryEn": "Croatia",
    "teamName": "快船",
    "birthDay": 858661200000,
    "country": "克罗地亚",
    "teamCityEn": "LA",
    "code": "ivica_zubac",
    "displayAffiliation": "Croatia",
    "displayName": "伊维察 祖巴茨哥哥", //"伊维察 祖巴茨"修改为"伊维察 祖巴茨哥哥"
    "schoolType": "",
    "teamConference": "西部",
    "teamConferenceEn": "Western",
    "weight": "108.9 公斤",
    "teamCity": "洛杉矶",
    "playYear": 3,
    "jerseyNo": "40",
    "teamNameEn": "Clippers",
    "draft": 2016,
    "displayNameEn": "Ivica Zubac",
    "heightValue": 2.16,
    "birthDayStr": "1997-03-18",
    "position": "中锋",
    "age": 22,
    "playerId": "1627826"
}
  • 响应
{
    "_index": "nba",
    "_type": "_doc",
    "_id": "566",
    "_version": 2,
    "result": "updated",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 566,
    "_primary_term": 1
}

如何重建索引

Elasticsearch是一个实时的分布式搜索引擎,为用户提供搜索服务,当我们决定存储某种数据时,在创建索引的时候需要将数据结构完整确定下来,于此同时索引的设定和很多固定配置将不能改变。当需要改变数据结构时,就需要重新建立索引,为此,Elastic团队提供了很多辅助工具帮助开发人员进行重建索引。步骤如下:

  1. nba取一个别名nba_latest, nba_latest作为对外使用
  • POST 请求
localhost:9200/_aliases
  • 请求体
{
  "actions": [
    {
      "add": {
        "index": "nba",
        "alias": "nba_latest"
      }
    }
  ]
}
  • 响应
{
  "acknowledged" : true
}
  1. 新增一个索引nba_20220101,结构复制于nba索引,根据业务要求修改字段
  • PUT 请求
localhost:9200/nba_20220101
  • 请求体
{
    "mappings": {
        "properties": {
            "age": {
                "type": "integer"
            },
            "birthDay": {
                "type": "date"
            },
            "birthDayStr": {
                "type": "keyword"
            },
            "code": {
                "type": "text"
            },
            "country": {
                "type": "keyword"
            },
            "countryEn": {
                "type": "keyword"
            },
            "displayAffiliation": {
                "type": "text"
            },
            "displayName": {
                "type": "text"
            },
            "displayNameEn": {
                "type": "text"
            },
            "draft": {
                "type": "long"
            },
            "heightValue": {
                "type": "float"
            },
            "jerseyNo": {
                "type": "keyword"
            },
            "playYear": {
                "type": "long"
            },
            "playerId": {
                "type": "keyword"
            },
            "position": {
                "type": "text"
            },
            "schoolType": {
                "type": "text"
            },
            "teamCity": {
                "type": "text"
            },
            "teamCityEn": {
                "type": "text"
            },
            "teamConference": {
                "type": "keyword"
            },
            "teamConferenceEn": {
                "type": "keyword"
            },
            "teamName": {
                "type": "keyword"
            },
            "teamNameEn": {
                "type": "keyword"
            },
            "weight": {
                "type": "text"
            }
        }
    }
}
  • 响应
{
    "acknowledged": true,
    "shards_acknowledged": true,
    "index": "nba_20220101"
}
  1. 将nba数据同步到nba_20220101
  • POST 请求
localhost:9200/_reindex  //同步请求 等待响应
localhost:9200/_reindex?wait_for_completion=false  // 异步请求 直接返回
  • 请求体
{
  "source": {
    "index": "nba"
  },
  "dest": {
    "index": "nba_20220101"
  }
}
  • 响应
{
  "took" : 102,
  "timed_out" : false,
  "total" : 566,
  "updated" : 0,
  "created" : 566,
  "deleted" : 0,
  "batches" : 1,
  "version_conflicts" : 0,
  "noops" : 0,
  "retries" : {
    "bulk" : 0,
    "search" : 0
  },
  "throttled_millis" : 0,
  "requests_per_second" : -1.0,
  "throttled_until_millis" : 0,
  "failures" : [ ]
}
  1. 给nba_20220101添加别名nba_latest,删除nba别名nba_latest
  • POST请求
localhost:9200/_aliases
  • 请求体
{
  "actions": [
    {
      "add": {
        "index": "nba_20220101",
        "alias": "nba_latest"
      }
    }
  ]
}
  • 响应
{
  "acknowledged" : true
}
  1. 删除nba索引
  • DELETE请求
localhost:9200/nba
  • 响应
{
  "acknowledged" : true
}

refresh操作

理想的搜索

  1. 新的数据一添加到索引中立马就能搜索到,但是真实情况不是这样的

  2. 我们使用链式命令请求,先添加一个文档,再立刻搜索

curl -X PUT localhost:9200/star/_doc/888 -H 'Content-Type: application/json' -d '{ "displayName": "蔡徐坤" }'

curl -X GET localhost:9200/star/_doc/_search?pretty
  1. 强制刷新
curl -X PUT localhost:9200/star/_doc/666?refresh -H 'Content-Type: application/json' -d '{ "displayName": "杨超越" }'

curl -X GET localhost:9200/star/_doc/_search?pretty
  1. 修改默认更新时间(默认时间是1s)
  • PUT 请求
localhost:9200/star/_settings
  • 请求体
{
  "index":{
    "refresh_interval": "5s"
  }
}
  • 响应
{
  "acknowledged" : true
}
  1. 将refresh关闭
  • PUT 请求
localhost:9200/star/_settings
  • 请求体
{
  "index":{
    "refresh_interval": "-1"
  }
}
  • 响应
{
  "acknowledged" : true
}

高亮查询

如果返回的结果集中很多符合条件的结果,那怎么能一眼就能看到我们想要的那个结果呢?比如,我们搜索姚明,在结果集中,将所有姚明高亮显示?

  • 请求
localhost:9200/nba_latest/_search
  • 请求体
{
  // 语义: 查找NBA james球员,对james做高亮显示
  "query": {
    "match": {
      "displayNameEn": "james"
    }
  },
  "highlight": { // 高亮关键字
    "fields": { // 对displayNameEn做高亮
      "displayNameEn": {}
    }
  },
  "size": 2
}

// 也可以自定义标签
{
  "query": {
    "match": {
      "displayNameEn": "james"
    }
  },
  "highlight": {
    "fields": {
      "displayNameEn": {
        // 定义高亮标签为 h1
        "pre_tags": ["<h1>"],
        "post_tags": ["</h1>"]

      }
    }
  },
  "size": 2
}
  • 响应
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 5,
      "relation" : "eq"
    },
    "max_score" : 4.699642,
    "hits" : [
      {
        "_index" : "nba_20220101",
        "_type" : "_doc",
        "_id" : "214",
        "_score" : 4.699642,
        "_source" : {
          "countryEn" : "United States",
          "teamName" : "火箭",
          "birthDay" : 620107200000,
          "country" : "美国",
          "teamCityEn" : "Houston",
          "code" : "james_harden",
          "displayAffiliation" : "Arizona State/United States",
          "displayName" : "詹姆斯 哈登",
          "schoolType" : "College",
          "teamConference" : "西部",
          "teamConferenceEn" : "Western",
          "weight" : "99.8 公斤",
          "teamCity" : "休斯顿",
          "playYear" : 10,
          "jerseyNo" : "13",
          "teamNameEn" : "Rockets",
          "draft" : 2009,
          "displayNameEn" : "James Harden",
          "heightValue" : 1.96,
          "birthDayStr" : "1989-08-26",
          "position" : "后卫",
          "age" : 30,
          "playerId" : "201935"
        },
        "highlight" : {
          // "<em> 包裹起来是 高亮的意思
          "displayNameEn" : [
            "<em>James</em> Harden"
          ]
        }
      },
      {
        "_index" : "nba_20220101",
        "_type" : "_doc",
        "_id" : "266",
        "_score" : 4.699642,
        "_source" : {
          "countryEn" : "United States",
          "teamName" : "国王",
          "birthDay" : 854082000000,
          "country" : "美国",
          "teamCityEn" : "Sacramento",
          "code" : "justin_james",
          "displayAffiliation" : "United States",
          "displayName" : "贾斯汀 詹姆斯",
          "schoolType" : "College",
          "teamConference" : "西部",
          "teamConferenceEn" : "Western",
          "weight" : "86.2 公斤",
          "teamCity" : "萨克拉门托",
          "playYear" : 0,
          "jerseyNo" : "",
          "teamNameEn" : "Kings",
          "draft" : 2019,
          "displayNameEn" : "Justin James",
          "heightValue" : 2.01,
          "birthDayStr" : "1997-01-24",
          "position" : "后卫-前锋",
          "age" : 22,
          "playerId" : "1629713"
        },
        "highlight" : {
          // "<em> 包裹起来是 高亮的意思
          "displayNameEn" : [
            "Justin <em>James</em>"
          ]
        }
      }
    ]
  }
}

查询建议

  • 查询建议是什么

查询建议,是为了给用户提供更好的搜索体验。包括:词条检查,自动补全

  • Suggester

(1)Term suggester
(2)Phrase suggester
(3)Completion suggester

text 指定搜索文本
field 获取建议词的搜索字段
analyzer 指定分词器
size 每个词返回的最大建议词数
sort 如何对建议词进行排序,可用选项:
score:先按评分排序、再按文档频率、term顺序排
frequency:先按文档频率排,再按评分、term顺序排
suggest_mode 建议模式,控制提供建议词的方式:
missing:仅在搜索的词项在索引中不存在时才提供建议词,默认值
popular:仅建议文档频率比搜索词项高的词
always:总是提供匹配的建议词

term suggester

term词条建议器 ,对给输入的文本进行分词,为每个分词提供词项建议

  • 请求
localhost:9200/nba_latest/_search
  • 请求体
{
  "suggest": {
    "my-suggest": {
      "text": "jamse", //用户可能输入错误 jsmes写成jamse
      "term": {
        "suggest_mode": "missing",
        "field": "displayNameEn"
      }
    }
  }
}
  • 响应
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "suggest" : {
    "my-suggest" : [
      {
        "text" : "jamse",
        "offset" : 0,
        "length" : 5,
        "options" : [
          {
            "text" : "james",
            "score" : 0.8,
            "freq" : 5
          },
          {
            "text" : "jamal",
            "score" : 0.6,
            "freq" : 2
          },
          {
            "text" : "jake",
            "score" : 0.5,
            "freq" : 1
          },
          {
            "text" : "jose",
            "score" : 0.5,
            "freq" : 1
          }
        ]
      },
      {
        "text" : "hardne",
        "offset" : 6,
        "length" : 6,
        "options" : [
          {
            "text" : "harden",
            "score" : 0.8333333,
            "freq" : 1
          }
        ]
      }
    ]
  }
}

phrase suggester

phrase短语建议,在term的基础上,会考量多个term之间的关系,比如是否同时出现在索引的原文里,相邻程度,以及词频等

  • 请求
localhost:9200/nba_latest/_search
  • 请求体
{
  "suggest": {
    "my-suggest": {
      "text": "jamse hardne",
      "phrase": { // 词组 对单词进行联系
        "field": "displayNameEn"
      }
    }
  }
}
  • 响应
{
  "took" : 26,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "suggest" : {
    "my-suggest" : [
      {
        "text" : "jamse hardne",
        "offset" : 0,
        "length" : 12,
        "options" : [
          {
            "text" : "james hardne",
            "score" : 0.0025682184
          },
          {
            "text" : "jamal hardne",
            "score" : 0.0016773979
          },
          {
            "text" : "jamse harden",
            "score" : 0.0016222595
          },
          {
            "text" : "jake hardne",
            "score" : 0.001299489
          },
          {
            "text" : "jose hardne",
            "score" : 0.001299489
          }
        ]
      }
    ]
  }
}

completion suggester

completion完成建议

  • 请求
localhost:9200/nba_latest/_search
  • 请求体
{
  "suggest": {
    "my-suggest": {
      "text": "Miam",
      "completion":{
        "field": "teamCityEn"
      }
    }
  }
}

版权声明:
作者:Joe.Ye
链接:https://www.appblog.cn/index.php/2023/03/12/elasticsearch-7-learning-advanced-search/
来源:APP全栈技术分享
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
ElasticSearch 7 学习(13)高级搜索
索引别名的使用 在开发中,随着业务需求的迭代,较老的业务逻辑就要面临更新甚至是重构,而对于es来说,为了适应新的业务逻辑,可能就要对原有的索引做一些修……
<<上一篇
下一篇>>
文章目录
关闭
目 录