基于ElasticSearch Suggest实现的搜索自动提示

1索引的创建
1.1创建索引映射

PUT  http://xxx:9200/suggest_test
{
    "settings": {
        "number_of_shards": 1
    },
    "mappings": {
        "_doc": {
            "properties": {
                "body": {
                    "type": "completion",
                    "analyzer": "ik_max_word"
                }
            }
        }
    }
}

1.2向索引中添加数据

PUT  http://xxx:9200/suggest_test/_doc/1
{
    "body": "付乔乔"
}

PUT  http://xxx:9200/suggest_test/_doc/4
{
    "body": "付乔乔超好看"
}


1.3 DSL搜索查看效果

POST http://xxx:9200/suggest_test/_search
{
    "suggest": {
        "blog-suggest": {
            "prefix": "付乔",
            "completion": {
                "field": "body",
                "size": 10,
                "skip_duplicates": true
            }
        }
    }
}

2 java后端代码

2.1 Controller层:

@Controller
@RequestMapping(name = "检索", value = "/enterprise/wechat")
public class WeChatMsgSearchController {

    @Autowired
    QueryMsgInfoService queryMsgInfoService;

    @RequestMapping("/getDemoHtml")
    public String getDemoHtml(){
        //此处是需要展示的html在templates下的具体路径
        return "login";
    }

    @RequestMapping(value = {"/suggest"}, method = {RequestMethod.GET})
    protected void tipTest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //中文转码
        request.setCharacterEncoding("UTF-8");
        response.setCharacterEncoding("UTF-8");
        //获取前端传入的数据
        String text = request.getParameter("prefix");
        List<String> list = queryMsgInfoService.querySuggestInfo(text);
        //将数组转换成字符串
        String str = StringUtils.collectionToDelimitedString(list, ",");
        //将处理好的数据传回给客户端
        response.getWriter().write(str);
    }

}

2.2 Service层:

public interface QueryMsgInfoService {
    List<String> querySuggestInfo(String prefix);
}

2.3 Impl层
        

@Service
    @Slf4j
    public class QueryMsgInfoServiceImpl implements QueryMsgInfoService {
        @Override
        public List<String> querySuggestInfo(String prefix) {
            try {
                // 1.Request
                SearchRequest request = new SearchRequest("suggest_test").types("_doc");
                // 2.DSL
                request.source().suggest(new SuggestBuilder().addSuggestion(
                        "blog-suggest",
                        SuggestBuilders.completionSuggestion("body")
                                .prefix(prefix)
                                .skipDuplicates(true)
                                .size(10)
                ));
                System.out.println("request = " + request);
                // 3.发起请求
                SearchResponse response = client.search(request, RequestOptions.DEFAULT);
                // 4.解析结果
                Suggest suggest = response.getSuggest();
                // 4.1.根据补全查询名称,获取补全结果
                CompletionSuggestion suggestions = suggest.getSuggestion("blog-suggest");
                // 4.2.获取options
                List<CompletionSuggestion.Entry.Option> options = suggestions.getOptions();
                // 4.3.遍历
                List<String> list = new ArrayList<>(options.size());
                for (CompletionSuggestion.Entry.Option option : options) {
                    String text = option.getText().toString();
                    list.add(text);
                }
                return list;
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
        }

3前端代码编写 
        3.1 引入依赖

 <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-thymeleaf</artifactId>
 </dependency>

        3.2 在resource目录下,新建templates目录,在下面编写login.html页面 

   <!DOCTYPE html>
        <html lang="en">
        <head>
          <meta charset="UTF-8">
          <title>Title</title>
          <script>
            window.onload=function(){
              // debugger;
              //获取文本输入框
              var textElment = document.getElementById("text");
              //获取下提示框
              var div = document.getElementById("tips");

              textElment.onkeyup=function(){
                //获取用户输入的值
                var text = textElment.value;
                //如果文本框中没有值,则下拉框被隐藏,不显示
                if(text==""){
                  div.style.display="none";
                  return;
                }
                //获取XMLHttpRequest对象
                var xhr = new XMLHttpRequest();
                //编写回调函数
                xhr.onreadystatechange=function(){
                  //判断回调的条件是否准备齐全
                  if(xhr.readyState==4){
                    if(xhr.status==200){
                      //取的服务器端传回的数据
                      var str = xhr.responseText;

                      //判断传回的数据是否为空,若是则直接返回,不显示
                      if(str==""){
                        return;
                      }
                      //我们将会在服务器端把数据用 , 隔开,当然这里也可以使用json
                      var result = str.split(",");
                      var childs = "";
                      //遍历结果集,将结果集中的每一条数据用一个div显示,把所有的div放入到childs中
                      for(var i=0; i<result.length;i++){
                        childs += "<div onclick='Write(this)' onmouseout='recoverColorwhenMouseout(this)' onmouseover='changeColorwhenMouseover(this)'>"+result[i]+"</div>";
                      }
                      //把childs 这div集合放入到下拉提示框的父div中,上面我们以获取了
                      div.innerHTML=childs;
                      div.style.display="block";

                    }
                  }
                }

                //创建与服务器的连接
                xhr.open("GET","/enterprise/wechat/suggest?prefix="+text);


                //发送
                xhr.send();
              }
            }
            //鼠标悬停时改变div的颜色
            function changeColorwhenMouseover(div){
              div.style.backgroundColor="blue";
            }
            //鼠标移出时回复div颜色
            function recoverColorwhenMouseout(div){
              div.style.backgroundColor="";
            }
            //当鼠标带点击div时,将div的值赋给输入文本框
            function Write(div){
              //将div中的值赋给文本框
              document.getElementById("text").value=div.innerHTML;

              //让下拉提示框消失

              div.parentNode.style.display="none";
            }
          </script>
        </head>

        <body>
        <h2>用户登录</h2>


          <!--
              文本输入框
           -->
          <div id="serach">
            <input type="text" name="text" id="text" />
            <input type="submit" value="搜索" />
          </div>

          <!--
           提示下拉框
          -->
          <div id="tips" style="display: none;
            width: 171px; border: 1px solid pink";>
          </div>

        </body>
        </html>

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值