• elasticsearch的搜索补全提示


    当用户在搜索框输入字符时,我们应该提示出与该字符有关的搜索项

    拼音分词器

    下载 

    要实现根据字母做补全,就必须对文档按照拼音分词,GitHub上有拼音分词插件

    GitHub - medcl/elasticsearch-analysis-pinyin: This Pinyin Analysis plugin is used to do conversion between Chinese characters and Pinyin.

    解压

    解压到一个文件夹中去

    上传 

    上传到服务器中,elasticsearch的plugin目录  

    重启 

    重启elasticsearch  

    docker restart es
    

     测试

    1. POST /_analyze
    2. {
    3. "text": "如家酒店还不错",
    4. "analyzer": "pinyin"
    5. }

    返回拼音 

    自定义分词器

    默认的拼音分词器会将每个汉字单独分为拼音,而我们希望的是每个词条形成一组拼音,需要对拼音分词器做个性化定制,形成自定义分词器。

    elasticsearch中分词器(analyzer)的组成包含三部分:

    • character filters:在tokenizer之前对文本进行处理。例如删除字符、替换字符

    • tokenizer:将文本按照一定的规则切割成词条(term)。例如keyword,就是不分词;还有ik_smart

    • tokenizer filter:将tokenizer输出的词条做进一步处理。例如大小写转换、同义词处理、拼音处理等

    自定义分词器 

    1. PUT /myanalyzer
    2. {
    3. "settings": {
    4. "analysis": {
    5. "analyzer": {
    6. "my_analyzer": {
    7. "tokenizer": "ik_max_word",
    8. "filter": "py"
    9. }
    10. },
    11. "filter": {
    12. "py": {
    13. "type": "pinyin",
    14. "keep_full_pinyin": false,
    15. "keep_joined_full_pinyin": true,
    16. "keep_original": true,
    17. "limit_first_letter_length": 16,
    18. "remove_duplicated_term": true,
    19. "none_chinese_pinyin_tokenize": false
    20. }
    21. }
    22. }
    23. },
    24. "mappings": {
    25. "properties": {
    26. "name": {
    27. "type": "text",
    28. "analyzer": "my_analyzer",
    29. "search_analyzer": "ik_smart"
    30. }
    31. }
    32. }
    33. }
    • analyzer自定义分词器 
    • my_analyzer分词器名称
    • filter自定义tokenizer filter
    • py过滤器名称
    • filter.type过滤器类型,这里是pinyin
    • name分词的字段

     测试

    1. POST /myanalyzer/_analyze
    2. {
    3. "text": ["华美达酒店还不错"],
    4. "analyzer": "my_analyzer"
    5. }

    结果

    自动补全查询 

    创建索引库

    1. PUT /hotel
    2. {
    3. "settings": {
    4. "analysis": {
    5. "analyzer": {
    6. "text_anlyzer": {
    7. "tokenizer": "ik_max_word",
    8. "filter": "py"
    9. },
    10. "completion_analyzer": {
    11. "tokenizer": "keyword",
    12. "filter": "py"
    13. }
    14. },
    15. "filter": {
    16. "py": {
    17. "type": "pinyin",
    18. "keep_full_pinyin": false,
    19. "keep_joined_full_pinyin": true,
    20. "keep_original": true,
    21. "limit_first_letter_length": 16,
    22. "remove_duplicated_term": true,
    23. "none_chinese_pinyin_tokenize": false
    24. }
    25. }
    26. }
    27. },
    28. "mappings": {
    29. "properties": {
    30. "id":{
    31. "type": "keyword"
    32. },
    33. "name":{
    34. "type": "text",
    35. "analyzer": "text_anlyzer",
    36. "search_analyzer": "ik_smart",
    37. "copy_to": "all"
    38. },
    39. "address":{
    40. "type": "keyword",
    41. "index": false
    42. },
    43. "price":{
    44. "type": "integer"
    45. },
    46. "score":{
    47. "type": "integer"
    48. },
    49. "brand":{
    50. "type": "keyword",
    51. "copy_to": "all"
    52. },
    53. "city":{
    54. "type": "keyword"
    55. },
    56. "starName":{
    57. "type": "keyword"
    58. },
    59. "business":{
    60. "type": "keyword",
    61. "copy_to": "all"
    62. },
    63. "location":{
    64. "type": "geo_point"
    65. },
    66. "pic":{
    67. "type": "keyword",
    68. "index": false
    69. },
    70. "all":{
    71. "type": "text",
    72. "analyzer": "text_anlyzer",
    73. "search_analyzer": "ik_smart"
    74. },
    75. "suggestion":{
    76. "type": "completion",
    77. "analyzer": "completion_analyzer"
    78. }
    79. }
    80. }
    81. }

    HotelDoc实体

    1. import lombok.Data;
    2. import lombok.NoArgsConstructor;
    3. import java.util.ArrayList;
    4. import java.util.Arrays;
    5. import java.util.Collections;
    6. import java.util.List;
    7. @Data
    8. @NoArgsConstructor
    9. public class HotelDoc {
    10. private Long id;
    11. private String name;
    12. private String address;
    13. private Integer price;
    14. private Integer score;
    15. private String brand;
    16. private String city;
    17. private String starName;
    18. private String business;
    19. private String location;
    20. private String pic;
    21. private Object distance;
    22. private Boolean isAD;
    23. private List suggestion;
    24. public HotelDoc(Hotel hotel) {
    25. this.id = hotel.getId();
    26. this.name = hotel.getName();
    27. this.address = hotel.getAddress();
    28. this.price = hotel.getPrice();
    29. this.score = hotel.getScore();
    30. this.brand = hotel.getBrand();
    31. this.city = hotel.getCity();
    32. this.starName = hotel.getStarName();
    33. this.business = hotel.getBusiness();
    34. this.location = hotel.getLatitude() + ", " + hotel.getLongitude();
    35. this.pic = hotel.getPic();
    36. // 组装suggestion
    37. if(this.business.contains("/")){
    38. // business有多个值,需要切割
    39. String[] arr = this.business.split("/");
    40. // 添加元素
    41. this.suggestion = new ArrayList<>();
    42. this.suggestion.add(this.brand);
    43. Collections.addAll(this.suggestion, arr);
    44. }else {
    45. this.suggestion = Arrays.asList(this.brand, this.business);
    46. }
    47. }
    48. }

    导入数据

    1. @Test
    2. void testBulkRequest() throws IOException {
    3. // 批量查询酒店数据
    4. List hotels = hotelService.list();
    5. // 1.创建Request
    6. BulkRequest request = new BulkRequest();
    7. // 2.准备参数,添加多个新增的Request
    8. for (Hotel hotel : hotels) {
    9. // 2.1.转换为文档类型HotelDoc
    10. HotelDoc hotelDoc = new HotelDoc(hotel);
    11. // 2.2.创建新增文档的Request对象
    12. request.add(new IndexRequest("hotel")
    13. .id(hotelDoc.getId().toString())
    14. .source(JSON.toJSONString(hotelDoc), XContentType.JSON));
    15. }
    16. // 3.发送请求
    17. client.bulk(request, RequestOptions.DEFAULT);
    18. }

    controller类

    1. import cn.itcast.hotel.pojo.PageResult;
    2. import cn.itcast.hotel.pojo.RequestParams;
    3. import cn.itcast.hotel.service.IHotelService;
    4. import org.springframework.beans.factory.annotation.Autowired;
    5. import org.springframework.web.bind.annotation.*;
    6. import java.util.List;
    7. import java.util.Map;
    8. @RestController
    9. @RequestMapping("/hotel")
    10. public class HotelController {
    11. @Autowired
    12. private IHotelService hotelService;
    13. // 搜索酒店数据
    14. @GetMapping("suggestion")
    15. public List getSuggestions(@RequestParam("key") String prefix) {
    16. return hotelService.getSuggestions(prefix);
    17. }
    18. }

    service类

    1. import cn.itcast.hotel.mapper.HotelMapper;
    2. import cn.itcast.hotel.pojo.Hotel;
    3. import cn.itcast.hotel.pojo.HotelDoc;
    4. import cn.itcast.hotel.pojo.PageResult;
    5. import cn.itcast.hotel.pojo.RequestParams;
    6. import cn.itcast.hotel.service.IHotelService;
    7. import com.alibaba.fastjson.JSON;
    8. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    9. import org.elasticsearch.action.search.SearchRequest;
    10. import org.elasticsearch.action.search.SearchResponse;
    11. import org.elasticsearch.client.RequestOptions;
    12. import org.elasticsearch.client.RestHighLevelClient;
    13. import org.elasticsearch.common.geo.GeoPoint;
    14. import org.elasticsearch.common.unit.DistanceUnit;
    15. import org.elasticsearch.index.query.BoolQueryBuilder;
    16. import org.elasticsearch.index.query.QueryBuilders;
    17. import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
    18. import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
    19. import org.elasticsearch.search.SearchHit;
    20. import org.elasticsearch.search.SearchHits;
    21. import org.elasticsearch.search.aggregations.AggregationBuilders;
    22. import org.elasticsearch.search.aggregations.Aggregations;
    23. import org.elasticsearch.search.aggregations.bucket.terms.Terms;
    24. import org.elasticsearch.search.sort.SortBuilders;
    25. import org.elasticsearch.search.sort.SortOrder;
    26. import org.elasticsearch.search.suggest.Suggest;
    27. import org.elasticsearch.search.suggest.SuggestBuilder;
    28. import org.elasticsearch.search.suggest.SuggestBuilders;
    29. import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
    30. import org.springframework.beans.factory.annotation.Autowired;
    31. import org.springframework.stereotype.Service;
    32. import java.io.IOException;
    33. import java.util.ArrayList;
    34. import java.util.HashMap;
    35. import java.util.List;
    36. import java.util.Map;
    37. @Service
    38. public class HotelService extends ServiceImpl implements IHotelService {
    39. @Autowired
    40. private RestHighLevelClient client;
    41. @Override
    42. public List getSuggestions(String prefix) {
    43. try {
    44. // 1.准备Request
    45. SearchRequest request = new SearchRequest("hotel");
    46. // 2.准备DSL
    47. request.source().suggest(new SuggestBuilder().addSuggestion(
    48. "suggestions",
    49. SuggestBuilders.completionSuggestion("suggestion")
    50. .prefix(prefix)
    51. .skipDuplicates(true)
    52. .size(10)
    53. ));
    54. // 3.发起请求
    55. SearchResponse response = client.search(request, RequestOptions.DEFAULT);
    56. // 4.解析结果
    57. Suggest suggest = response.getSuggest();
    58. // 4.1.根据补全查询名称,获取补全结果
    59. CompletionSuggestion suggestions = suggest.getSuggestion("suggestions");
    60. // 4.2.获取options
    61. List options = suggestions.getOptions();
    62. // 4.3.遍历
    63. List list = new ArrayList<>(options.size());
    64. for (CompletionSuggestion.Entry.Option option : options) {
    65. String text = option.getText().toString();
    66. list.add(text);
    67. }
    68. return list;
    69. } catch (IOException e) {
    70. throw new RuntimeException(e);
    71. }
    72. }
    73. }

    测试 

  • 相关阅读:
    数据结构与算法设计分析—— 数据结构及常用算法
    XSS漏洞介绍
    微信qq拦截检测易语言代码
    UEFI之DXE阶段
    20240810将荣品RK3588S-AHD开发板的USB3.0口切换为HOST模式接鼠标和U盘
    React学习3(React组件)
    计算机毕业设计(附源码)python职业高中智慧教学系统
    【数组拷贝+二维数组遍历】
    Python数据分析与机器学习44-Python生成时间序列
    2022年大一网页期末作业(纯HTML+CSS实现)(1)
  • 原文地址:https://blog.csdn.net/qq_63431773/article/details/132688848