Elasticsearch实战之搜索项目

Posted 一心同学

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Elasticsearch实战之搜索项目相关的知识,希望对你有一定的参考价值。

📢📢📢📣📣📣 

哈喽!大家好,我是【一心同学】,一位上进心十足的【Java领域博主】!😜😜😜

✨【一心同学】的写作风格:喜欢用【通俗易懂】的文笔去讲解每一个知识点,而不喜欢用【高大上】的官方陈述。

✨【一心同学】博客的领域是【面向后端技术】的学习,未来会持续更新更多的【后端技术】以及【学习心得】。

✨如果有对【后端技术】感兴趣的【小可爱】,欢迎关注一心同学】💞💞💞

❤️❤️❤️感谢各位大可爱小可爱!❤️❤️❤️ 


目录

前言

环境准备

一、创建项目

1.1 依赖导入

1.2 确保版本统一

1.3 创建ES索引

二、编写配置文件

三、注册客户端配置

四、获取数据

4.1 依赖

4.2 获取网页数据

五、编写实体类

六、编写service

6.1 存放数据

6.2 分页查询

6.3  高亮搜索

七、编写controller层

7.1 编写前端前端控制类

7.2 编写数据控制类

八、前后端分离

8.1 获取vue和axios依赖

8.2 编写前端页面

小结


前言

我们学了Elasticsearch的各种基本操作,可能还觉得对ES的操作并不是特别熟悉,这时候我们就应该来完成一个小项目的开发,从而巩固我们的知识!

我们先来看最终的项目效果:

环境准备

JDK:1.8

Elasticsearch:7.6.1

SpringBoot:2.6.4

在开始讲解之前,【一心同学】先扔出我自己的目录,大家可以参考一下:

一、创建项目

1.1 依赖导入

创建一个SpringBoot项目并在创建时自动导入以下依赖:

(1)导入开发基本依赖

(2)导入Web依赖

(3)导入数据交互Thymeleaf

(4)导入Elasticsearch依赖

(5)手动导入以下两个依赖

		
<!--        解析网页jsoup,获取某东数据所需要的-->
        <dependency>
			<groupId>org.jsoup</groupId>
			<artifactId>jsoup</artifactId>
			<version>1.10.2</version>
		</dependency>

		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.62</version>
		</dependency>

总的依赖如下:

 <dependencies>

        <dependency>
            <groupId>org.jsoup</groupId>
            <artifactId>jsoup</artifactId>
            <version>1.10.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

1.2 确保版本统一

我们要确保导入的ES依赖与我们自己的ES版本是一致的,故继续在pom.xml中进行以下配置:

    <properties>
        <java.version>1.8</java.version>
<!--        确保版本统一-->
        <elasticsearch.version>7.6.1</elasticsearch.version>
    </properties>

1.3 创建ES索引

创建ES索引es_jd:

二、编写配置文件

application.properties:

# 配置端口号
server.port=9090
# 关闭thymeleaf缓存
spring.thymeleaf.cache=false

三、注册客户端配置

ES客户端进行注册,以便可以访问到我们自己的Elasticsearch服务。

package com.yixin.config;


import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ElasticSearchClientConfig 
    // 注册 rest高级客户端
    @Bean
    public RestHighLevelClient restHighLevelClient()
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("127.0.0.1",9200,"http")
                )
        );
        return client;
    

四、获取数据

注意:我们对商城的数据并不打算自己手动输入,而是直接获取其他网页的数据。

4.1 依赖

对爬取所依赖的网页解析架包我们已经导进来了,不需要再导入了,就是这个:

<!--        解析网页jsoup,获取某东数据所需要的-->
        <dependency>
			<groupId>org.jsoup</groupId>
			<artifactId>jsoup</artifactId>
			<version>1.10.2</version>
		</dependency>

4.2 获取网页数据

我们先去该页面打开其开发者模式,来查看其前端代码:

通过以上页面的分析,我们得到以下信息:

J_goodsList:存放所有商品的容器
li标签:存放每一个商品的小容器
p-img:存放商品图片
p-name:存放商品名称
p-price:存放商品价格

注意

对于商品的图片我们并没办法直接获取,因为某东对图片的加载是属于懒加载机制的,<img>src链接并拿不到我们要的图片,我们应该直接去获取其懒加载里面的图片地址

 编写网页解析工具类:

package com.yixin.utils;

import com.yixin.pojo.Content;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

@Component
public class htmlParseUtil 

    public static List<Content> parseJD(String keyword) throws IOException 
        /// 使用前需要联网
        // 请求url
        String url = "http://search.jd.com/search?keyword=" + keyword;
        // 1.解析网页(jsoup 解析返回的对象是浏览器Document对象)
        Document document = Jsoup.parse(new URL(url), 30000);
        // 使用document可以使用在js对document的所有操作
        // 2.获取元素(通过id)
        Element j_goodsList = document.getElementById("J_goodsList");
        // 3.获取J_goodsList ul 每一个 li
        Elements lis = j_goodsList.getElementsByTag("li");
//        System.out.println(lis);
        // 4.获取li下的 img、price、name
        // list存储所有li下的内容
        List<Content> contents = new ArrayList<Content>();
        for (Element li : lis) 
            // 由于网站图片使用懒加载,将src属性替换为data-lazy-img
            String img = li.getElementsByTag("img").eq(0).attr("data-lazy-img");// 获取li下 第一张图片
            String name = li.getElementsByClass("p-name").eq(0).text();
            String price = li.getElementsByClass("p-price").eq(0).text();
            // 封装为对象
            Content content = new Content(name,img,price);
            // 添加到list中
            contents.add(content);
        
//        System.out.println(contents);
        // 5.返回 list
        return contents;
    

五、编写实体类

我们需要从某东网页拿到图片地址名称价格这三个属性,我们将其包装为一个实体类,拿到数据后直接封装为对象即可。

package com.kuang.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Content implements Serializable 
    private static final long serialVersionUID = -8049497962627482693L;
    private String name;
    private String img;
    private String price;


 

六、编写service

6.1 存放数据

获取商品数据并存放到ES索引es_jd

    @Autowired
    private RestHighLevelClient restHighLevelClient; 
   
    //获取数据存放到ES的索引es_jd中
    public Boolean parseContent(String keywords) throws Exception
        List<Content> contents=new HtmlParseUtil().parseJD(keywords);
        BulkRequest bulkRequest=new BulkRequest();
        bulkRequest.timeout("2m");

        for(int i=0;i<contents.size();i++)
            bulkRequest.add(
                    new IndexRequest("es_jd")
                    .source(JSON.toJSONString(contents.get(i)), XContentType.JSON)
            );
            

        
        BulkResponse bulk=restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
        return  !bulk.hasFailures();
    

6.2 分页查询

根据关键字进行分页查询

    // 2、根据keyword分页查询结果
    public List<Map<String, Object>> search(String keyword, Integer pageIndex, Integer pageSize) throws IOException 
        if (pageIndex < 0)
            pageIndex = 0;
        

        SearchRequest jd_goods = new SearchRequest("es_jd");
        // 创建搜索源建造者对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 条件采用:精确查询 通过keyword查字段name
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", keyword);
        searchSourceBuilder.query(termQueryBuilder);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));// 60s

        // 分页
        searchSourceBuilder.from(pageIndex);
        searchSourceBuilder.size(pageSize);

        // 高亮
        // ....
        // 搜索源放入搜索请求中
        jd_goods.source(searchSourceBuilder);
        // 执行查询,返回结果
        SearchResponse searchResponse = restHighLevelClient.search(jd_goods, RequestOptions.DEFAULT);
        restHighLevelClient.close();
        // 解析结果
        SearchHits hits = searchResponse.getHits();
        List<Map<String,Object>> results = new ArrayList<>();
        for (SearchHit documentFields : hits.getHits()) 
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
            results.add(sourceAsMap);
        
        // 返回查询的结果
        return results;
    

6.3  高亮搜索

对输入的关键字进行高亮搜索返回

 public List<Map<String, Object>> highlightSearch(String keyword, Integer pageIndex, Integer pageSize) throws IOException 
        SearchRequest searchRequest = new SearchRequest("es_jd");
      
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

        // 精确查询,添加查询条件
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", keyword);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchSourceBuilder.query(termQueryBuilder);

        // 分页
        searchSourceBuilder.from(pageIndex);
        searchSourceBuilder.size(pageSize);

        // 高亮 =========
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);

        // 执行查询
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // 解析结果 ==========
        SearchHits hits = searchResponse.getHits();
        List<Map<String, Object>> results = new ArrayList<>();
       
        for (SearchHit documentFields : hits.getHits()) 

            // 使用新的字段值(高亮),覆盖旧的字段值
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
            // 高亮字段
            Map<String, HighlightField> highlightFields = documentFields.getHighlightFields();
            HighlightField name = highlightFields.get("name");
            // 替换
            if (name != null)
                Text[] fragments = name.fragments();
                StringBuilder new_name = new StringBuilder();
                for (Text text : fragments) 
                    new_name.append(text);
                
                sourceAsMap.put("name",new_name.toString());
            
            results.add(sourceAsMap);
        
        return results;
    

该类的全部代码如下:

package com.yixin.service;

import com.alibaba.fastjson.JSON;
import com.yixin.pojo.Content;
import com.yixin.utils.HtmlParseUtil;
import org.elasticsearch.action.bulk.BulkRequest;
import org.elasticsearch.action.bulk.BulkResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Service
public class ContentService 

    public static void main(String[] args) throws  Exception
        System.out.println(new ContentService().parseContent("java"));
    


    //获取数据存放到ES的索引es_jd中
    public Boolean parseContent(String keywords) throws Exception
        List<Content> contents=new HtmlParseUtil().parseJD(keywords);
        BulkRequest bulkRequest=new BulkRequest();
        bulkRequest.timeout("2m");

        for(int i=0;i<contents.size();i++)
            bulkRequest.add(
                    new IndexRequest("es_jd")
                    .source(JSON.toJSONString(contents.get(i)), XContentType.JSON)
            );

        
        BulkResponse bulk=restHighLevelClient.bulk(bulkRequest,RequestOptions.DEFAULT);
        return  !bulk.hasFailures();
    
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    // 2、根据keyword分页查询结果
    public List<Map<String, Object>> search(String keyword, Integer pageIndex, Integer pageSize) throws IOException 
        if (pageIndex < 0)
            pageIndex = 0;
        

        SearchRequest jd_goods = new SearchRequest("es_jd");

        // 创建搜索源建造者对象
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 条件采用:精确查询 通过keyword查字段name
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", keyword);
        searchSourceBuilder.query(termQueryBuilder);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));// 60s

        // 分页
        searchSourceBuilder.from(pageIndex);
        searchSourceBuilder.size(pageSize);

        // 高亮
        // ....
        // 搜索源放入搜索请求中
        jd_goods.source(searchSourceBuilder);
        // 执行查询,返回结果
        SearchResponse searchResponse = restHighLevelClient.search(jd_goods, RequestOptions.DEFAULT);
        restHighLevelClient.close();
        // 解析结果
        SearchHits hits = searchResponse.getHits();
        List<Map<String,Object>> results = new ArrayList<>();
        for (SearchHit documentFields : hits.getHits()) 
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();
            results.add(sourceAsMap);
        

        // 返回查询的结果
        return results;
    
    // 3、 在2的基础上进行高亮查询
    public List<Map<String, Object>> highlightSearch(String keyword, Integer pageIndex, Integer pageSize) throws IOException 
        SearchRequest searchRequest = new SearchRequest("es_jd");

        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        // 精确查询,添加查询条件
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", keyword);
        searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        searchSourceBuilder.query(termQueryBuilder);

        // 分页
        searchSourceBuilder.from(pageIndex);
        searchSourceBuilder.size(pageSize);

        // 高亮 =========
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name");
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        searchSourceBuilder.highlighter(highlightBuilder);

        // 执行查询
        searchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);

        // 解析结果 ==========
        SearchHits hits = searchResponse.getHits();
        List<Map<String, Object>> results = new ArrayList<>();

        for (SearchHit documentFields : hits.getHits()) 
            // 使用新的字段值(高亮),覆盖旧的字段值
            Map<String, Object> sourceAsMap = documentFields.getSourceAsMap();

            // 高亮字段
            Map<String, HighlightField> highlightFields = documentFields.getHighlightFields();
            HighlightField name = highlightFields.get("name");

            // 替换
            if (name != null)
                Text[] fragments = name.fragments();
                StringBuilder new_name = new StringBuilder();
                for (Text text : fragments) 
                    new_name.append(text);
                
                sourceAsMap.put("name",new_name.toString());
            
            results.add(sourceAsMap);
        
        return results;
    

七、编写controller层

7.1 编写前端前端控制类

IndexController类:

package com.yixin.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class IndexController 
    @GetMapping("/","index")
    public String index()
        return "index";
    

7.2 编写数据控制类

ContentController类:

package com.yixin.controller;

import com.yixin.service.ContentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;
import java.util.List;
import java.util.Map;

@RestController
public class ContentController 

    @Autowired
    private ContentService contentService;

    @GetMapping("/parse/keywords")
    public Boolean parse(@PathVariable("keywords") String keywords) throws  Exception
        return  contentService.parseContent(keywords);
    



    @ResponseBody
    @GetMapping("/search/keyword/pageIndex/pageSize")
    public List<Map<String, Object>> parse(@PathVariable("keyword") String keyword,
                                           @PathVariable("pageIndex") Integer pageIndex,
                                           @PathVariable("pageSize") Integer pageSize) throws IOException
        return contentService.search(keyword,pageIndex,pageSize);
    



    @ResponseBody
    @GetMapping("/h_search/keyword/pageIndex/pageSize")
    public List<Map<String, Object>> highlightParse(@PathVariable("keyword") String keyword,
                                                    @PathVariable("pageIndex") Integer pageIndex,
                                                    @PathVariable("pageSize") Integer pageSize) throws IOException 
        System.out.println("*********************************");
        return contentService.highlightSearch(keyword,pageIndex,pageSize);
    

八、前后端分离

8.1 获取vue和axios依赖

前提:已经安装了nodejs环境

在任意目录下打开控制台分别输入以下命令:

npm install vue
npm install axios

我们分别拿到axios.min.jsvue.min.js这两个文件,并存放在js目录中。

 

8.2 编写前端页面

由于这个页面的css和js样式【一心同学】没办法展示出来,大家可以自己去找一个前端模板,然后按我的思路来写就可以了。

编写templates目录下的index.html:

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="utf-8"/>
    <title>Java-ES仿某东实战</title>
    <link rel="stylesheet" th:href="@/css/style.css"/>
    <script th:src="@/js/jquery.min.js"></script>
</head>
<body class="pg">
<div class="page">
    <div id="app" class=" mallist tmall- page-not-market ">
        <!-- 头部搜索 -->
        <div id="header" class=" header-list-app">
            <div class="headerLayout">
                <div class="headerCon ">
                    <!-- Logo-->
                    <h1 id="mallLogo">
                        <img th:src="@/images/jdlogo.png" alt="">
                    </h1>
                    <div class="header-extra">
                        <!--搜索-->
                        <div id="mallSearch" class="mall-search">
                            <form name="searchTop" class="mallSearch-form clearfix">
                                <fieldset>
                                    <legend>京东搜索</legend>
                                    <div class="mallSearch-input clearfix">
                                        <div class="s-combobox" id="s-combobox-685">
                                            <div class="s-combobox-input-wrap">
                                                <input v-model="keyword"  type="text" autocomplete="off" id="mq"
                                                       class="s-combobox-input"  aria-haspopup="true">
                                            </div>
                                        </div>
                                        <button type="submit" @click.prevent="searchKey" id="searchbtn">搜索</button>
                                    </div>
                                </fieldset>
                            </form>
                            <ul class="relKeyTop">
                                <li><a>Java</a></li>
                                <li><a>Vue</a></li>
                                <li><a>Linux</a></li>
                                <li><a>Elasticsearch</a></li>
                            </ul>
                        </div>
                    </div>
                </div>
            </div>
        </div>

        <!-- 商品详情页面 -->
        <div id="content">
            <div class="main">
                <!-- 品牌分类 -->
                <form class="navAttrsForm">
                    <div class="attrs j_NavAttrs" style="display:block">
                        <div class="brandAttr j_nav_brand">
                            <div class="j_Brand attr">
                                <div class="attrKey">
                                    品牌
                                </div>
                                <div class="attrValues">
                                    <ul class="av-collapse row-2">
                                        <li><a href="#"> 一心同学 </a></li>
                                        <li><a href="#"> Java </a></li>
                                    </ul>
                                </div>
                            </div>
                        </div>
                    </div>
                </form>
                <!-- 排序规则 -->
                <div class="filter clearfix">
                    <a class="fSort fSort-cur">综合<i class="f-ico-arrow-d"></i></a>
                    <a class="fSort">人气<i class="f-ico-arrow-d"></i></a>
                    <a class="fSort">新品<i class="f-ico-arrow-d"></i></a>
                    <a class="fSort">销量<i class="f-ico-arrow-d"></i></a>
                    <a class="fSort">价格<i class="f-ico-triangle-mt"></i><i class="f-ico-triangle-mb"></i></a>
                </div>
                <!-- 商品详情 -->
                <div class="view grid-nosku" >
                    <div class="product" v-for="result in results">
                        <div class="product-iWrap">
                            <!--商品封面-->
                            <div class="productImg-wrap">
                                <a class="productImg">
                                    <img :src="result.img">
                                </a>
                            </div>
                            <!--价格-->
                            <p class="productPrice">
                                <em v-text="result.price"></em>
                            </p>
                            <!--标题-->
                            <p class="productTitle">
                                <a v-html="result.name"></a>
                            </p>
                            <!-- 店铺名 -->
                            <div class="productShop">
                                <span>店铺: 一心同学 </span>
                            </div>
                            <!-- 成交信息 -->
                            <p class="productStatus">
                                <span>月成交<em>999笔</em></span>
                                <span>评价 <a>3</a></span>
                            </p>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
<script th:src="@/js/vue.min.js"></script>
<script th:src="@/js/axios.min.js"></script>
<script>
    new Vue(
        el:"#app",
        data:
            "keyword": '', // 搜索的关键字
            "results":[] // 后端返回的结果
        ,
        methods:
            searchKey()
                var keyword = this.keyword;
                console.log(keyword);
                axios.get('h_search/'+keyword+'/0/20').then(response=>
                    console.log(response.data);
                    this.results=response.data;
                )
            
        
    );
</script>
</body>
</html>

现在整个项目就搭建成功了!

但注意现在我们的ES索引中还没有数据,还记得我们刚刚写了一个获取数据的方法吗,我们在浏览器中输入:http://localhost:9090/parse/java

 这样我们ES中就存放了关于Java的数据,这些数据都是从某东爬取过来的:

现在我们启动我们自己的项目:

由于我们没有输入任何关键词所以没有数据,现在我们往里面输入java,就可以看到有关java类型的书籍了:

至此,就大功告成了! 


小结

以上就是【一心同学】通过浏览网上资料而整理的【用Elasticsearch仿某东的搜索】项目,大家在学完一个知识过后,可以自己动手做个【小项目】,从而来对知识进行【巩固】。

如果这篇【文章】有帮助到你,希望可以给【一心同学】点个👍,创作不易,相比官方的陈述,我更喜欢用【通俗易懂】的文笔去讲解每一个知识点,如果有对【后端技术】感兴趣的小可爱,也欢迎关注❤️❤️❤️ 【一心同学】❤️❤️❤️,我将会给你带来巨大的【收获与惊喜】💕💕!

以上是关于Elasticsearch实战之搜索项目的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch连续剧之实战篇Java操作es

elasticsearch实战三部曲之三:搜索操作

Elasticsearch全文搜索引擎实战之Kibana搭建

《ElasticSearch6.x实战教程》之分词

Elasticsearch 5.4新闻搜索项目实战

Elasticsearch 5.4新闻搜索项目实战