广告
返回顶部
首页 > 资讯 > 数据库 >如何使用elasticsearch搭建自己的搜索系统
  • 553
分享到

如何使用elasticsearch搭建自己的搜索系统

2024-04-02 19:04:59 553人浏览 泡泡鱼
摘要

这期内容当中小编将会给大家带来有关如何使用elasticsearch搭建自己的搜索系统,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。什么是e

这期内容当中小编将会给大家带来有关如何使用elasticsearch搭建自己的搜索系统,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。

什么是elasticsearch#

Elasticsearch 是一个开源的高度可扩展的全文搜索和分析引擎,拥有查询近实时的超强性能。

大名鼎鼎的Lucene 搜索引擎被广泛用于搜索领域,但是操作复杂繁琐,总是让开发者敬而远之。而 Elasticsearch将 Lucene 作为其核心来实现所有索引和搜索的功能,通过简单的 RESTful 语法来隐藏掉 Lucene 的复杂性,从而让全文搜索变得简单

ES在Lucene基础上,提供了一些分布式的实现:集群,分片,复制等。

搜索为什么不用Mysql而用es#

我们本文案例是一个迷你商品搜索系统,为什么不考虑使用mysql来实现搜索功能呢?原因如下:

  • Mysql默认使用innodb引擎,底层采用b+树的方式来实现,而Es底层使用倒排索引的方式实现,使用倒排索引支持各种维度的分词,可以掌控不同粒度的搜索需求。(MYSQL8版本也支持了全文检索,使用倒排索引实现,有兴趣可以去看看两者的差别)

  • 如果使用MySQL的%key%的模糊匹配来与es的搜索进行比较,在8万数据量时他们的耗时已经达到40:1左右,毫无疑问在速度方面es完胜。

es在大厂中的应用情况#

  • es运用最广泛的是elk组合来对日志进行搜索分析

  • 58安全部门、京东订单中心几乎全采用es来完成相关信息的存储与检索

  • es在tob的项目中也用于各种检索与分析

  • 在c端产品中,企业通常自己基于Lucene封装自己的搜索系统,为了适配公司营销战略、推荐系统等会有更多定制化的搜索需求

es客户端选型#

spring-boot-starter-data-elasticsearch#

我相信你看到的网上各类公开课视频或者小项目均推荐使用这款SpringBoot整合过的es客户端,但是我们要say no!

如何使用elasticsearch搭建自己的搜索系统

此图是引入的最新版本的依赖,我们可以看到它所使用的es-high-client也为6.8.7,而es7.x版本都已经更新很久了,这里许多新特性都无法使用,所以版本滞后是他最大的问题。而且它的底层也是highclient,我们操作highclient可以更灵活。我呆过的两个公司均未采用此客户端。

elasticsearch-rest-high-level-client#

这是官方推荐的客户端,支持最新的es,其实使用起来也很便利,因为是官方推荐所以在特性的操作上肯定优于前者。而且该客户端与TransportClient不同,不存在并发瓶颈的问题,官方首推,必为精品!

搭建自己的迷你搜索系统#

引入es相关依赖,除此之外需引入springboot-WEB依赖、jackson依赖以及lombok依赖等。

Copy	<properties>
        <es.version>7.3.2</es.version>
    </properties>
		<!-- high client-->
	<dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-high-level-client</artifactId>
        <version>${es.version}</version>
        <exclusions>
            <exclusion>
                <groupId>org.elasticsearch.client</groupId>
                <artifactId>elasticsearch-rest-client</artifactId>
            </exclusion>
            <exclusion>
                <groupId>org.elasticsearch</groupId>
                <artifactId>elasticsearch</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.elasticsearch</groupId>
        <artifactId>elasticsearch</artifactId>
        <version>${es.version}</version>
    </dependency>
    <!--rest low client high client以来低版本client所以需要引入-->
    <dependency>
        <groupId>org.elasticsearch.client</groupId>
        <artifactId>elasticsearch-rest-client</artifactId>
        <version>${es.version}</version>
    </dependency>

es配置文件es-config.properties

Copyes.host=localhost
es.port=9200
es.token=es-token
es.charset=UTF-8
es.scheme=Http
es.client.connectTimeOut=5000
es.client.SocketTimeout=15000

封装RestHighLevelClient

Copy@Configuration@PropertySource("classpath:es-config.properties")public class RestHighLevelClientConfig {    @Value("${es.host}")    private String host;    @Value("${es.port}")    private int port;    @Value("${es.scheme}")    private String scheme;    @Value("${es.token}")    private String token;    @Value("${es.charset}")    private String charSet;    @Value("${es.client.connectTimeOut}")    private int connectTimeOut;    @Value("${es.client.socketTimeout}")    private int socketTimeout;    @Bean
    public RestClientBuilder restClientBuilder() {
        RestClientBuilder restClientBuilder = RestClient.builder(                new HttpHost(host, port, scheme)
        );
        Header[] defaultHeaders = new Header[]{                new BasicHeader("Accept", "*
    public CreateIndexResponse createIndex(String indexName, String settings, String mapping) throws IOException {
        CreateIndexRequest request = new CreateIndexRequest(indexName);        if (null != settings && !"".equals(settings)) {
            request.settings(settings, XContentType.JSON);
        }        if (null != mapping && !"".equals(mapping)) {
            request.mapping(mapping, XContentType.jsON);
        }        return client.indices().create(request, RequestOptions.DEFAULT);
    }    
    public boolean indexExists(String indexName) throws IOException {
        GetIndexRequest request = new GetIndexRequest(indexName);        return client.indices().exists(request, RequestOptions.DEFAULT);
    }    
    
    public SearchResponse search(String field, String key, String rangeField, String 
                                 from, String to,String termField, String termVal, 
                                 String ... indexNames) throws IOException{
        SearchRequest request = new SearchRequest(indexNames);
        SearchSourceBuilder builder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        boolQueryBuilder.must(new MatchQueryBuilder(field, key)).must(new RangeQueryBuilder(rangeField).from(from).to(to)).must(new TerMQueryBuilder(termField, termVal));
        builder.query(boolQueryBuilder);
        request.source(builder);
        log.info("[搜索语句为:{}]",request.source().toString());        return client.search(request, RequestOptions.DEFAULT);
    }    
    public BulkResponse importAll(String indexName, boolean isAutoId, String  source) throws IOException{        if (0 == source.length()){            //todo 抛出异常 导入数据为空
        }
        BulkRequest request = new BulkRequest();
        Jsonnode jsonNode = mapper.readTree(source);        if (jsonNode.isArray()) {            for (JsonNode node : jsonNode) {                if (isAutoId) {
                    request.add(new IndexRequest(indexName).source(node.asText(), XContentType.JSON));
                } else {
                    request.add(new IndexRequest(indexName)
                            .id(node.get("id").asText())
                            .source(node.asText(), XContentType.JSON));
                }
            }
        }        return client.bulk(request, RequestOptions.DEFAULT);
    }

创建索引,这里的settings是设置索引是否设置复制节点、设置分片个数,mappings就和数据库中的表结构一样,用来指定各个字段的类型,同时也可以设置字段是否分词(我们这里使用ik中文分词器)、采用什么分词方式。

Copy   @Test
    public void createIdx() throws IOException {
        String settings = "" +                "  {\n" +                "      \"number_of_shards\" : \"2\",\n" +                "      \"number_of_replicas\" : \"0\"\n" +                "   }";
        String mappings = "" +                "{\n" +                "    \"properties\": {\n" +                "      \"itemId\" : {\n" +                "        \"type\": \"keyWord\",\n" +                "        \"ignore_above\": 64\n" +                "      },\n" +                "      \"urlId\" : {\n" +                "        \"type\": \"keyword\",\n" +                "        \"ignore_above\": 64\n" +                "      },\n" +                "      \"sellAddress\" : {\n" +                "        \"type\": \"text\",\n" +                "        \"analyzer\": \"ik_max_word\", \n" +                "        \"search_analyzer\": \"ik_smart\",\n" +                "        \"fields\": {\n" +                "          \"keyword\" : {\"ignore_above\" : 256, \"type\" : \"keyword\"}\n" +                "        }\n" +                "      },\n" +                "      \"courierFee\" : {\n" +                "        \"type\": \"text\n" +                "      },\n" +                "      \"promotions\" : {\n" +                "        \"type\": \"text\",\n" +                "        \"analyzer\": \"ik_max_word\", \n" +                "        \"search_analyzer\": \"ik_smart\",\n" +                "        \"fields\": {\n" +                "          \"keyword\" : {\"ignore_above\" : 256, \"type\" : \"keyword\"}\n" +                "        }\n" +                "      },\n" +                "      \"originalPrice\" : {\n" +                "        \"type\": \"keyword\",\n" +                "        \"ignore_above\": 64\n" +                "      },\n" +                "      \"startTime\" : {\n" +                "        \"type\": \"date\",\n" +                "        \"fORMat\": \"yyyy-MM-dd HH:mm:ss\"\n" +                "      },\n" +                "      \"endTime\" : {\n" +                "        \"type\": \"date\",\n" +                "        \"format\": \"yyyy-MM-dd HH:mm:ss\"\n" +                "      },\n" +                "      \"title\" : {\n" +                "        \"type\": \"text\",\n" +                "        \"analyzer\": \"ik_max_word\", \n" +                "        \"search_analyzer\": \"ik_smart\",\n" +                "        \"fields\": {\n" +                "          \"keyword\" : {\"ignore_above\" : 256, \"type\" : \"keyword\"}\n" +                "        }\n" +                "      },\n" +                "      \"serviceGuarantee\" : {\n" +                "        \"type\": \"text\",\n" +                "        \"analyzer\": \"ik_max_word\", \n" +                "        \"search_analyzer\": \"ik_smart\",\n" +                "        \"fields\": {\n" +                "          \"keyword\" : {\"ignore_above\" : 256, \"type\" : \"keyword\"}\n" +                "        }\n" +                "      },\n" +                "      \"venue\" : {\n" +                "        \"type\": \"text\",\n" +                "        \"analyzer\": \"ik_max_word\", \n" +                "        \"search_analyzer\": \"ik_smart\",\n" +                "        \"fields\": {\n" +                "          \"keyword\" : {\"ignore_above\" : 256, \"type\" : \"keyword\"}\n" +                "        }\n" +                "      },\n" +                "      \"currentPrice\" : {\n" +                "        \"type\": \"keyword\",\n" +                "        \"ignore_above\": 64\n" +                "      }\n" +                "   }\n" +                "}";
        clientService.createIndex("idx_item", settings, mappings);
    }

分词技巧

  • 索引时最小分词,搜索时最大分词,例如"Java知音"索引时分词包含Java、知音、音、知等,最小粒度分词可以让我们匹配更多的检索需求,但是我们搜索时应该设置最大分词,用“Java”和“知音”去匹配索引库,得到的结果更贴近我们的目的,

  • 对分词字段同时也设置keyword,便于后续排查错误时可以精确匹配搜索,快速定位。

我们向es导入十万条淘宝双11活动数据作为我们的样本数据,数据结构如下所示

Copy{	"_id": "https://detail.tmall.com/item.htm?id=538528948719\u0026skuId=3216546934499",	"卖家地址": "上海",	"快递费": "运费: 0.00元",	"优惠活动": "满199减10,满299减30,满499减60,可跨店",	"商品ID": "538528948719",	"原价": "2290.00",	"活动开始时间": "2016-11-11 00:00:00",	"活动结束时间": "2016-11-11 23:59:59",	"标题": "【天猫海外直营】 ReFa CARAT RAY 黎珐 双球滚轮波光美容仪",	"服务保障": "正品保证;赠运费险;极速退款;七天退换",	"会场": "进口尖货",	"现价": "1950.00"}

调用上面封装的批量导入方法进行导入

Copy    @Test
    public void importAll() throws IOException {
        clientService.importAll("idx_item", true, itemService.getItemsJson());
    }

我们调用封装的搜索方法进行搜索,搜索产地为武汉、价格在11-149之间的相关酒产品,这与我们淘宝中设置筛选条件搜索商品操作一致。

Copy    @Test
    public void search() throws IOException {
        SearchResponse search = clientService.search("title", "酒", "currentPrice",                "11", "149", "sellAddress", "武汉");
        SearchHits hits = search.getHits();
        SearchHit[] hits1 = hits.getHits();        for (SearchHit documentFields : hits1) {
            System.out.println( documentFields.getSourceAsString());
        }
    }

我们得到以下搜索结果,其中_score为某一项的得分,商品就是按照它来排序

Copy    {      "_index": "idx_item",      "_type": "_doc",      "_id": "Rw3G7HEBDGgXwwHKFPCb",      "_score": 10.995819,      "_source": {        "itemId": "525033055044",        "urlId": "https://detail.tmall.com/item.htm?id=525033055044&skuId=def",        "sellAddress": "湖北武汉",        "courierFee": "快递: 0.00",        "promotions": "满199减10,满299减30,满499减60,可跨店",        "originalPrice": "3768.00",        "startTime": "2016-11-01 00:00:00",        "endTime": "2016-11-11 23:59:59",        "title": "酒嗨酒 西班牙原瓶原装进口红酒蒙德干红葡萄酒6只装整箱送酒具",        "serviceGuarantee": "破损包退;正品保证;公益宝贝;不支持7天退换;极速退款",        "venue": "食品主会场",        "currentPrice": "151.00"
      }
    }

扩展性思考#

  • 商品搜索权重扩展,我们可以利用多种收费方式智能为不同店家提供增加权重,增加曝光度适应自身的营销策略。同时我们经常发现淘宝搜索前列的商品许多为我们之前查看过的商品,这是通过记录用户行为,跑模型等方式智能为这些商品增加权重。

  • 分词扩展,也许因为某些商品的特殊性,我们可以自定义扩展分词字典,更精准、人性化的搜索。

  • 高亮功能,es提供highlight高亮功能,我们在淘宝上看到的商品展示中对搜索关键字高亮,就是通过这种方式来实现。 高亮使用方式

上述就是小编为大家分享的如何使用elasticsearch搭建自己的搜索系统了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注编程网数据库频道。

您可能感兴趣的文档:

--结束END--

本文标题: 如何使用elasticsearch搭建自己的搜索系统

本文链接: https://www.lsjlt.com/news/60294.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何使用elasticsearch搭建自己的搜索系统
    这期内容当中小编将会给大家带来有关如何使用elasticsearch搭建自己的搜索系统,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。什么是e...
    99+
    2022-10-18
  • 用ElasticSearch搭建自己的搜索和分析引擎
    导语:互联网产品中的检索功能随处可见。当你的项目规模是百度大搜|商搜或者微信公众号搜索这种体量的时候,自己开发一个搜索引擎,加入各种定制的需求和优化,是非常自然的事情。但如果只是普通的中小型项目甚至创业团队...
    99+
    2022-10-18
  • 使用Java Minio搭建自己的文件系统详解
    目录前言1、Minio介绍2、Minio安装与启动3、Minio控制台创建存储桶4、存储桶权限5、控制台实现文件的上传与下载6、使用Springboot与Minio整合实现文件的增删...
    99+
    2022-11-12
  • 如何搭建自己的云服务器呢苹果系统
    首先,我们需要了解一些基础的云服务器配置,包括云主机的选型、存储的选型、带宽的选型等等。在选型方面,需要根据自己的需求和实际情况来选择,同时也要考虑到所需的硬件资源和软件配置等方面。比如,如果我们需要搭建自己的服务器应用程序,那么就需要考虑...
    99+
    2023-10-28
    自己的 苹果 服务器
  • 如何使用Flask搭建ES搜索引擎
    本篇内容主要讲解“如何使用Flask搭建ES搜索引擎”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何使用Flask搭建ES搜索引擎”吧!1 配置文件Config.py#coding:utf-8...
    99+
    2023-06-16
  • 如何搭建自己的云服务器呢苹果系统版本
    一、选择合适的操作系统和软件 首先,选择适合自己的操作系统和软件非常重要。不同的操作系统和软件适用于不同的场景和需求。例如,对于一些小型企业和个人用户,可以选择一些轻量级的Linux操作系统和Solaris操作系统,而对于大型企业和机构,...
    99+
    2023-10-27
    自己的 苹果 版本
  • 详解如何在Win系统中搭建自己的Git远程仓库
    在这个信息化的时代,程序员们必然会经常使用版本控制工具来方便管理自己的代码,Git作为分布式版本控制系统的代表,已经成为了程序员必备的技能之一。在我们平时的开发过程中,我们通常将本地的代码提交到远程仓库中,以便将代码同步到其他计算机上。在这...
    99+
    2023-10-22
  • 如何用DevUI搭建自己的Angular组件库
    目录前言创建组件库关键配置修改目录布局调整库构建关键配置开发一个Alert组件组件功能介绍组件结构分解定义输入输出定义布局测试Alert组件开发态引用组件编写单元测试发布组件前言 作...
    99+
    2022-11-12
  • gitee如何搭建自己的博客并使用自定义域名
    Gitee是一款优秀的码云平台,它可以为用户提供代码托管、项目管理、团队协作等多种有用的功能。但是,有些人不知道,Gitee还可以用来搭建自己的博客,并且还可以使用自定义域名,接下来,本文就将为大家详细介绍如何使用Gitee搭建自己的博客并...
    99+
    2023-10-22
  • 如何用自己的电脑搭建云服务器
    以下是用自己的电脑搭建云服务器的一般步骤: 安装云服务器:首先,需要购买一个云服务器。您可以直接在网上购买,或者向提供云服务器的公司提出请求购买。 配置云服务器:一旦您购买了云服务器,就需要对其进行配置。这可能包括安装必要的软件包,添加...
    99+
    2023-10-26
    自己的 如何用 服务器
  • 如何搭建一套自己的蜜罐系统来收集恶意软件样本
    引言本文将介绍如何搭建自己的蜜罐(dionaea)。我想说的是,我们大多数人都喜欢逆向工程二进制文件。同时,我们中的许多人都对恶意软件很着迷。那么,为什么不把它们和一些正在被开发利用的恶意软件结合起来呢?我所要讲的是如何在Amazon We...
    99+
    2023-06-04
  • 钉钉如何建立自己的项目管理系统
    首先,要建立一个好的项目管理系统,就需要考虑到项目的整体性和可行性。一个完整的项目管理系统应该包括以下几个方面: 任务分配和协作机制:在任务分配方面,应该考虑到任务的重要性、优先级、时间紧迫性和可行性等因素,同时也应该考虑到每个任务的具...
    99+
    2023-10-28
    自己的 管理系统 项目
  • 使用PHP商城开发,如何搭建自己的秒杀网站
    近年来,秒杀网站已经成为了电子商务中的一个重要组成部分,对于快速推广产品、吸引用户等方面都具有重要作用。不过,如何搭建一个自己的秒杀网站却是许多电子商务从业人员面临的难题。在本文中,我们将介绍如何利用PHP商城开发搭建自己的秒杀网站。什么是...
    99+
    2023-05-14
    PHP商城开发 秒杀网站搭建 自主搭建网站
  • 多ip香港vps租用如何搭建自己的网站
    搭建自己的网站需要以下步骤:1.购买域名:首先需要购买一个域名,可以在国内的域名注册商进行购买。2.购买VPS:在国外的VPS服务商...
    99+
    2023-05-30
    多ip香港vps租用 香港vps vps
  • 如何用自己的电脑搭建云服务器账号
    以下是用自己的电脑搭建云服务器账号的步骤: 准备计算机硬件和设备:计算机是搭建云服务器的必备硬件设备。建议您将计算机硬件从品牌型号中选择最适合您需求的型号,例如Intel Xeon E3 1230v2 CPU或AMD Ryzen 5 1...
    99+
    2023-10-27
    自己的 如何用 账号
  • 如何搭建一个属于自己的网站(使用宝塔面板)
    1.购买域名与服务器 域名 简单的解释一下,我们购买的域名会给我们一个公网ip,通常这个公网ip是很难记.所以我们可以将域名与ip进行"绑定". 域名的话建议购买一个有意义,不要太贵的.注意次年续费的...
    99+
    2023-09-10
    服务器 centos nginx php
  • 如何使用vue3搭建后台系统
    今天小编给大家分享一下如何使用vue3搭建后台系统的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。首先使用npm 或者yarn...
    99+
    2023-07-06
  • 如何用自己的电脑搭建云服务器账号呢
    云服务器的基本配置 在搭建云服务器之前,我们需要选择合适的服务器品牌和服务器型号,例如Amazon Web Services(AWS)或Microsoft Azure。不同的云服务商提供的配置和价格可能会有所不同,因此我们需要仔细查看...
    99+
    2023-10-28
    自己的 如何用 账号
  • 北京虚拟主机租用如何搭建自己的网站
    以下是北京虚拟主机租用搭建自己的网站的步骤:1. 购买虚拟主机:选择一家可靠的虚拟主机提供商,购买适合自己的虚拟主机。2. 域名注册...
    99+
    2023-05-29
    北京虚拟主机 虚拟主机
  • Win8系统自带搜索功能如何关闭以便使用第三方服务
      有些系统功能虽然方便用户使用,但体验并不如第三方服务。就如Win8的搜索功能,就让不少用户嫌弃。如果大家不想用它,可以将它关闭。   操作方法   第一步、按下Win+R组合键,在运行命令输入框中输入&...
    99+
    2022-06-04
    第三方 搜索功能 系统自带
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作