springboot+ Elasticsearch+suggest搜索框全文补齐

根据观察百度,京东等搜索框在输入一个字或者几个字时会有一个下拉框进行相关的查询这个就是补齐

首先需要在es中新建一个用于搜索的index,这个就相当于规定了搜索时的关键词

PUT /blog1
{
  "mappings": {
    "doc" : {
      "properties" : {
        "title" : {
          "type": "text",
          "analyzer": "ik_max_word",
          "fields": {
            "suggest" : {
              "type" : "completion",
              "analyzer": "ik_max_word"
            }
          }
        },
        "content": {
          "type": "text",
          "analyzer": "ik_max_word"
        }
      }
    }
  }
}

新建好index后可以添加几条数据

PUT /blog/1
{
  "title": "中国人",
  "content": "建设建设"
}
PUT /blog/2
{
  "title": "中华人民共和国",
  "content": "成立时间"
}
PUT /blog/3
{
  "title": "中国的制造",
  "content": "中国制造业世界领先"
}

添加完成后可以查询看看

GET /blog/_search
{
  "suggest": {
    "my-suggest" : {
      "prefix" : "中国",
      "completion" : {
        "field" : "title.suggest"
      }
    }
  }
}

如果出现的数据全是中国作为前缀的那么结果就正确

与springboot进行结合

@PostMapping("/searchsuggest")
    public Object getSearchSuggest(String key) {
        CompletionSuggestionBuilder suggestion = SuggestBuilders
                .completionSuggestion("title.suggest").prefix(key).size(20).skipDuplicates(true);
        SuggestBuilder suggestBuilder = new SuggestBuilder();
        suggestBuilder.addSuggestion("doc", suggestion);
        //ESBlog1.class用于确定是哪一个index,ESBlog1是一个实体类
        SearchResponse response = template.suggest(suggestBuilder, ESBlog1.class);
        Suggest suggest = response.getSuggest();

        Set<String> keywords = null;
        if (suggest != null) {
            keywords = new HashSet<>();
            List<? extends Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option>> entries
                    = suggest.getSuggestion("doc").getEntries();

            for (Suggest.Suggestion.Entry<? extends Suggest.Suggestion.Entry.Option> entry : entries) {
                for (Suggest.Suggestion.Entry.Option option: entry.getOptions()) {
                    // 最多返回9个数据, 每个长度最大为20
                    String keyword = option.getText().string();
                    if (!StringUtils.isEmpty(keyword) && keyword.length() <= 20) {
                       
                        keywords.add(keyword);
                        if (keywords.size() >= 9) {
                            break;
                        }
                    }
                }
            }
        }
        return keywords;
    }

ESBlog1实体类

package com.example.springbootelasticsearch.espojo;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.util.Date;

@Data
//相当于表
@Document(indexName = "blog1",type = "doc",useServerConfiguration = true,createIndex = false)
public class ESBlog1 {
    @Id
    private Integer id;
    //添加需要分词的字段用 @Field(type = FieldType.Text,analyzer = "ik_max_word")
    @Field(type = FieldType.Text,analyzer = "ik_max_word")
    private String title;
    @Field(type = FieldType.Text,analyzer = "ik_max_word")
    private String author;
    @Field(type = FieldType.Text,analyzer = "ik_max_word")
    private  String content;
    @Field(type = FieldType.Date,format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")
    private Date createTime;
    @Field(type = FieldType.Date,format = DateFormat.custom,pattern = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")
    private  Date updateTime;
}

如需了解es配置和logstash等配置可看我主页

下面是一些不成熟的建议:
如果全文检索和补齐搜索用同一个index可能全文检索的准确会出现误差,所以我在同一个es中新建两个index,这两个index的数据都是一致的,都是在数据库中实时的导入的,补齐搜索用一个,全文检索用一个,这样保证数据的一致也能将全文检索和补齐搜索分离。只是我自己在应用中出现的问题,仅供参考。
此情况下mysql.conf文件需要调整多添加一个elasticsearch模块

input{
	jdbc{
           #jdbc驱动包位置
           jdbc_driver_library =>"/Users/zhangxianzeng/Downloads/elasticsearchquanbuwenjian/logstash-6.3.2/mysql-connector-java-8.0.16.jar"
           #要使用的驱动包类,有过开发经验的都应该知道这个
           jdbc_driver_class =>"com.mysql.jdbc.Driver"
           #mysql数据库连接信息
           jdbc_connection_string =>"jdbc:mysql://127.0.0.1:3306/blog"
           #mysql用户名
           jdbc_user =>"root"
           #mysql密码
           jdbc_password =>"zhangxian11"
           #定时任务,多久执行一次查询,默认是一分钟,如何想要没有延迟,可以使用schedule =>"* * * * *"
           schedule =>"* * * * *"
           #清空上一次的sql_last_value记录
           clean_run =>true
           #你想要执行的语句
           statement =>"SELECT * FROM t_blog WHERE update_time > :sql_last_value AND update_time < NOW() ORDER BY update_time desc"
	}
}
output{
	elasticsearch{
	#es host:port
	hosts=>["127.0.0.1:9200"]
#索引
index=>"blog"

#_id
document_id=>"%{id}"
	}
//加一个elasticsearch模块
  elasticsearch{
  #es host:port
  hosts=>["127.0.0.1:9200"]
#索引
index=>"blog1"

#_id
document_id=>"%{id}"
  }
}

每一次重启logstash时需要将其data中的文件全部删除否则会报错
持续更新。。。。

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值