zoukankan      html  css  js  c++  java
  • ElasticSearch搜索引擎在JavaWeb项目中的应用

    近几篇ElasticSearch系列:

    1、阿里云服务器Linux系统安装配置ElasticSearch搜索引擎

    2、Linux系统中ElasticSearch搜索引擎安装配置Head插件

    3、ElasticSearch搜索引擎安装配置中文分词器IK插件

    4、ElasticSearch搜索引擎安装配置拼音插件pinyin

    5、ElasticSearch搜索引擎在JavaWeb项目中的应用 

    一、前言

    前四篇简单介绍了ElasticSearch(以下简称ES)在阿里云服务器Linux系统上的部署配置等。本篇将简述一下ES在JavaWeb项目中的应用。本项目前端框架是Vue.js,前后端数据交互采用是常用的SSM框架,项目管理工具为Maven,ES为6.3.2版本。

    二、正文

    1、ES在Maven中添加相应依赖,如下所示:

     1 <dependency>
     2     <groupId>org.elasticsearch</groupId>
     3     <artifactId>elasticsearch</artifactId>
     4     <version>6.3.2</version>
     5 </dependency>
     6 <dependency>
     7     <groupId>org.elasticsearch.client</groupId>
     8     <artifactId>transport</artifactId>
     9     <version>6.3.2</version>
    10 </dependency>

    2、@Configuration注解新建的 “ElasticSearchConfig” 类,用来初始化ES客户端TransportClient连接,通过setting来创建,若不指定则默认链接的集群名为elasticsearch,如下图所示:

     1 @Configuration
     2 public class ElasticSearchConfig {
     3 
     4     @Bean
     5     public TransportClient client() throws UnknownHostException {
     6         Settings settings = Settings.builder().build();
     7         TransportClient client = new PreBuiltTransportClient(settings)
     8                 .addTransportAddress(new TransportAddress(InetAddress.getByName("部署ES的IP地址"), 9300));
     9         return client;
    10     }
    11 }

    3、jsp里首先需要导入jquery与Vue,然后css样式仅供参考,如下图所示:

     1 <div id="search_main" style="position: relative;top: -360px;left: -200px; 100%;height: 50px;text-align: center">
     2     <input id="search_input1" type="text" name="search1" placeholder="请输入企业名称。如“阿里巴巴”或“alibaba”"
     3            style="height: 50px; 720px;border: none;font-size: 18px;" onkeypress="EnterPress(event)" onkeydown="EnterPress()"
     4            v-model="searchText" v-on:keyup="showName(searchText)"/>
     5     <img id="voice" src="icon/voice1.png" width="35" height="35" style="position: absolute;left: 1145px;top: 7px;"/>
     6     <button id="search_button1" type="button" style="position: relative;left: -4px;top: 1px;height: 50px; 100px;border: none;background-color: #1db5ee">
     7         <font size="4" color="white" style="align-content: center">搜索</font>
     8     </button>
     9     <font id="searchType" style="display: none">企业名</font>
    10     <div id="parentRelationSearch" v-for="(company, cIndex) in companyList" style="position: relative;top: 0px;left: 474px;height: auto; 719px;background-color: #ffffff;z-index: 99">
    11         <div class="relationSearch" v-on:click="putVal(company.name)" v-on:mouseenter="mouseEnter($event)" v-on:mouseleave="mouseLeave($event)" style="position: relative;top: 0px;left: 0px; 100%;height: 35px;border-bottom: 1px solid #e8e8e8;line-height: 35px;">
    12             <font size="2" style="position: absolute;left: 5px">{{company.name}}</font>
    13             <font size="1.5" style="position: absolute;left: 92%;">{{company.score}}</font>
    14         </div>
    15     </div>
    16 </div>

    4、id为search_main的元素为Vue实例挂载的元素节点,以及showName函数(ajax请求)为keyup事件putVal函数(将用户选中的元素值赋值给搜索框)为click事件,mouseEnter、mouseLeave函数分别为mouseenter、mouseleave事件,如下图所示:

     1 var vm1 = new Vue({
     2     el: '#search_main',
     3     data: {
     4         searchText: "",
     5         companyList: [],
     6     },
     7     mounted: function () {
     8         this.showName();
     9         this.putVal();
    10         this.mouseEnter();
    11         this.mouseLeave();
    12     },
    13     methods: {
    14         putVal: function (val) {
    15             $("#search_input1").val(val);
    16             $(".relationSearch").hide();
    17             document.getElementById("search_input1").focus();
    18         },
    19         showName: function (key) {
    20             console.log(key);
    21             if (key.length != 0) {
    22                 var searchType = document.getElementById("searchType").innerText;
    23                 if (searchType == "全部" || searchType == "企业名") {
    24                     $(".relationSearch").show();
    25                     var _this = this;
    26                     this.$http.get("auto_think.do?key=" + key).then(function (jsonResult) {
    27                         _this.companyList = (jsonResult.body);
    28                     });
    29                 }
    30             } else {
    31                 $(".relationSearch").hide();
    32             }
    33         },
    34         mouseEnter: function ($event) {
    35             $event.currentTarget.className = "relationSearch searchActive";
    36         },
    37         mouseLeave: function ($event) {
    38             $event.currentTarget.className = "relationSearch";
    39         }
    40     }
    41 });

    上述mouseEnter函数是用于动态添加class,用以实现鼠标移入则修改元素的背景功能:

    1 .searchActive{
    2     background-color:#e8e8e8;
    3 }

    5、QueryBuilder是ES提供的一个查询接口,进行单个匹配值为key的文档。SearchRequestBuilder根据索引与类型构造查询请求,设置查询条件和分页参数,再获取返回值并进行处理,最后返回,如下图所示:

     1 package controller;
     2 
     3 import entity.ElasticSearchResult;
     4 import org.elasticsearch.action.index.IndexResponse;
     5 import org.elasticsearch.action.search.SearchRequestBuilder;
     6 import org.elasticsearch.action.search.SearchResponse;
     7 import org.elasticsearch.client.transport.TransportClient;
     8 import org.elasticsearch.common.xcontent.XContentBuilder;
     9 import org.elasticsearch.common.xcontent.XContentFactory;
    10 import org.elasticsearch.index.query.QueryBuilder;
    11 import org.elasticsearch.index.query.QueryBuilders;
    12 import org.elasticsearch.search.SearchHit;
    13 import org.elasticsearch.search.SearchHits;
    14 import org.springframework.beans.factory.annotation.Autowired;
    15 import org.springframework.stereotype.Controller;
    16 import org.springframework.web.bind.annotation.GetMapping;
    17 import org.springframework.web.bind.annotation.RequestParam;
    18 import org.springframework.web.bind.annotation.ResponseBody;
    19 
    20 import java.io.IOException;
    21 import java.math.BigDecimal;
    22 import java.util.ArrayList;
    23 import java.util.List;
    24 
    25 @Controller
    26 public class ElasticSearchController {
    27 
    28     @Autowired
    29     private TransportClient client;
    30 
    31     //搜索自动联想
    32     @GetMapping("/auto_think.do")
    33     @ResponseBody
    34     public List<ElasticSearchResult> findIndexRecordByName(@RequestParam(name = "key") String key) {
    35         // 构造查询请求
    36         QueryBuilder bq = QueryBuilders.matchQuery("name.pinyin", key);
    37         SearchRequestBuilder searchRequest = client.prepareSearch("medcl").setTypes("folks");
    38 
    39         // 设置查询条件和分页参数
    40         int start = 0;
    41         int size = 5;
    42         searchRequest.setQuery(bq).setFrom(start).setSize(size);
    43 
    44         // 获取返回值,并进行处理
    45         SearchResponse response = searchRequest.execute().actionGet();
    46         SearchHits shs = response.getHits();
    47         List<ElasticSearchResult> esResultList = new ArrayList<>();
    48         for (SearchHit hit : shs) {
    49             ElasticSearchResult esResult = new ElasticSearchResult();
    50             double score = hit.getScore();
    51             BigDecimal b = new BigDecimal(score);
    52             score = b.setScale(3, BigDecimal.ROUND_HALF_UP).doubleValue();
    53             String name = (String) hit.getSourceAsMap().get("name");
    54             System.out.println("score:" + score + "name:" + name);
    55             esResult.setScore(score);
    56             esResult.setName(name);
    57             esResultList.add(esResult);
    58         }
    59         return esResultList;
    60     }
    61     
    62 }

    下述为ElasticSearchResult实体类:

     1 package entity;
     2 
     3 public class ElasticSearchResult {
     4 
     5     private double score;
     6 
     7     private String name;
     8 
     9     public ElasticSearchResult() {
    10     }
    11 
    12     public double getScore() {
    13         return score;
    14     }
    15 
    16     public void setScore(double score) {
    17         this.score = score;
    18     }
    19 
    20     public String getName() {
    21         return name;
    22     }
    23 
    24     public void setName(String name) {
    25         this.name = name;
    26     }
    27 }

    再附上向指定索引与类型添加、删除、更新文档函数代码,如下所示:

     1 /**
     2  * 添加文档
     3  * @param name
     4  */
     5 public void addByName(String name) {
     6     try {
     7         XContentBuilder content = XContentFactory.jsonBuilder()
     8                 .startObject().field("name", name).endObject();
     9         client.prepareIndex("medcl", "folks")
    10                 .setSource(content).get();
    11         System.out.println("ElasticSearch添加文档成功。");
    12     } catch (IOException e) {
    13         System.out.println("ElasticSearch添加文档出错。");
    14         e.printStackTrace();
    15     }
    16 }
    17 
    18 /**
    19  * 删除文档
    20  * @param name
    21  */
    22 public void deleteByName(String name) {
    23     BulkRequestBuilder bulkRequest = client.prepareBulk();
    24     SearchResponse response = client.prepareSearch("medcl").setTypes("folks")
    25             .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
    26             .setQuery(QueryBuilders.termQuery("name", name))
    27             .setFrom(0).setSize(20).setExplain(true).execute().actionGet();
    28     for(SearchHit hit : response.getHits()){
    29         String id = hit.getId();
    30         bulkRequest.add(client.prepareDelete("medcl", "folks", id).request());
    31     }
    32     BulkResponse bulkResponse = bulkRequest.get();
    33 
    34     if (bulkResponse.hasFailures()) {
    35         System.out.println("ElasticSearch删除文档出错。");
    36         for(BulkItemResponse item : bulkResponse.getItems()){
    37             System.out.println(item.getFailureMessage());
    38         }
    39     }else {
    40         System.out.println("ElasticSearch删除文档成功。");
    41     }
    42 }
    43 
    44 /**
    45  * 更新文档
    46  * @param beforeName
    47  * @param afterName
    48  */
    49 public void updateByName(String beforeName,String afterName){
    50     SearchResponse response = client.prepareSearch("medcl").setTypes("folks")
    51             .setSearchType(SearchType.DFS_QUERY_THEN_FETCH)
    52             .setQuery(QueryBuilders.termQuery("name", beforeName))
    53             .setFrom(0).setSize(20).setExplain(true).execute().actionGet();
    54     try {
    55         for(SearchHit hit : response.getHits()){
    56             UpdateRequest updateRequest = new UpdateRequest();
    57             updateRequest.index("medcl");
    58             updateRequest.type("folks");
    59             updateRequest.id(hit.getId());
    60             updateRequest.doc(XContentFactory.jsonBuilder().startObject().field("name",afterName).endObject());
    61             client.update(updateRequest).get();
    62         }
    63         System.out.println("ElasticSearch更新文档成功。");
    64     }catch (Exception e){
    65         System.out.println("ElasticSearch更新文档出错。");
    66         e.printStackTrace();
    67     }
    68 }

    最后附上功能演示效果图,如下图所示:

    至此是对ElasticSearch搜索引擎在JavaWeb项目中的应用的一个简单介绍。

    如有疏漏错误之处,还请不吝赐教!

  • 相关阅读:
    基于OpenSSL自建CA和颁发SSL证书
    SSL与TLS的区别以及介绍
    Ubuntu中Nginx的安装与配置
    Openssl源代码整理学习---含P7/P10/P12说明
    动态加载js文件
    常用方法
    对reducers 理解
    小复习(3)
    如何使移动web页面禁止横屏?
    九个Console命令,让 JS 调试更简单
  • 原文地址:https://www.cnblogs.com/yijialong/p/9729988.html
Copyright © 2011-2022 走看看