ElasticSearch-分布式多用户能力的全文搜索引擎

ElasticSearch

学习视频地址
基本概念讲解博客
中文文档

  • Lucene是一套信息检索包,jar包,不包含搜索引擎系统
  • ElasticSearch是基于Lucene做了一些封装和增强
  • 数据分析ELK技术:ElasticSearch+logstash+kibana

Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎。Elasticsearch用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。官方客户端在Java、.NET(C#)、PHP、Python、Apache Groovy、Ruby和许多其他语言中都是可用的。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr,也是基于Lucene。

安装ElasticSearch

安装相关

ElasticSearch基本概念

  • 索引(Index)
    ES将数据存储于一个或多个索引中,索引是具有类似特性的文档的集合。类比传统的关系型数据库领域来说,索引相当于SQL中的一个数据库,或者一个数据存储方案(schema)。索引由其名称(必须为全小写字符)进行标识,并通过引用此名称完成文档的创建、搜索、更新及删除操作。一个ES集群中可以按需创建任意数目的索引。

  • 类型(Type)
    类型是索引内部的逻辑分区(category/partition),然而其意义完全取决于用户需求。因此,一个索引内部可定义一个或多个类型(type)。一般来说,类型就是为那些拥有相同的域的文档做的预定义。例如,在索引中,可以定义一个用于存储用户数据的类型,一个存储日志数据的类型,以及一个存储评论数据的类型。类比传统的关系型数据库领域来说,类型相当于“表”。

  • 文档(Document)
    文档是Lucene索引和搜索的原子单位,它是包含了一个或多个域的容器,基于JSON格式进行表示。文档由一个或多个域组成,每个域拥有一个名字及一个或多个值,有多个值的域通常称为“多值域”。每个文档可以存储不同的域集,但同一类型下的文档至应该有某种程度上的相似之处。

  • 映射(Mapping)
    ES中,所有的文档在存储之前都要首先进行分析。用户可根据需要定义如何将文本分割成token、哪些token应该被过滤掉,以及哪些文本需要进行额外处理等等。另外,ES还提供了额外功能,例如将域中的内容按需排序。事实上,ES也能自动根据其值确定域的类型。

  • 节点(Node)
    运行了单个实例的ES主机称为节点,它是集群的一个成员,可以存储数据、参与集群索引及搜索操作。类似于集群,节点靠其名称进行标识,默认为启动时自动生成的随机Marvel字符名称。用户可以按需要自定义任何希望使用的名称,但出于管理的目的,此名称应该尽可能有较好的识别性。节点通过为其配置的ES集群名称确定其所要加入的集群。

  • 分片(Shard)和副本(Replica)
    ES的“分片(shard)”机制可将一个索引内部的数据分布地存储于多个节点,它通过将一个索引切分为多个底层物理的Lucene索引完成索引数据的分割存储功能,这每一个物理的Lucene索引称为一个分片(shard)。每个分片其内部都是一个全功能且独立的索引,因此可由集群中的任何主机存储。创建索引时,用户可指定其分片的数量,默认数量为5个。

IK分词器插件

  • 把一段中文划分为一个个关键字
  • IK分词器提供两个分词算法:
    • ik_smart(最少切分):不会重复
    • ik_max_word(最细粒度划分)
  • 安装插件,在kibana中测试
    1212

ik分词器增加自定义配置

  • 配置文件:elasticsearch-7.8.0\plugins\ik\config\IKAnalyzer.cfg.xml
  • config目录下新建dic文件,添加自己的词
  • 重启es,就可以匹配自己添加的词库了
    1212

Rest风格

  • Rest是一种软件架构风格,而不是标准,只是提供一组设计原则和约束条件
  • 关于索引的基本操作
methodurl地址描述
PUTlocalhost:9200/索引名称/类型名称/文档id创建文档(指定文档id)
POSTlocalhost:9200/索引名称/类型名称/创建文档(随机文档id)
POSTlocalhost:9200/索引名称/类型名称/文档id/_update修改文档
DELETElocalhost:9200/索引名称/类型名称/文档id删除文档
GETlocalhost:9200/索引名称/类型名称/文档id查询文档(通过文档id)
POSTlocalhost:9200/索引名称/类型名称/_search查询所有数据
  • 添加一个索引
PUT /test1/type1/1
{
	"name": "huang",
	"age": 18
}
GET test1		#获得索引信息
GET _cat/indices?v	#_cat可以获得es当前的很多信息

文档查询

  • 查处结果中有_score选项,匹配度越高,分值越高
  • 查询参数体中编辑参数:
    • query:match:匹配数据
    • _source:结果过滤
    • sort:排序

SpringBoot集成ES

官方文档

  1. 原生依赖
<dependency>
    <groupId>org.elasticsearch.client</groupId>
    <artifactId>elasticsearch-rest-high-level-client</artifactId>
    <version>7.8.1</version>
</dependency>
  1. springboot的es版本设置为和自己的一样
    <properties>
        <java.version>11</java.version>
    <!--自定义ES版本-->
        <elasticsearch.version>7.8.0</elasticsearch.version>
    </properties>
  1. 注入bean
@Configuration
public class ESconfig {
    @Bean
    public RestHighLevelClient restHighLevelClient(){
        RestHighLevelClient client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("localhost", 9200, "http")));
        return client;
    }
}
  1. 测试索引操作
@SpringBootTest
class TestApplicationTests {

    @Autowired
    @Qualifier(value = "restHighLevelClient")
    private RestHighLevelClient client;

    @Test
    void testCreate() throws IOException {
        //创建索引请求
        CreateIndexRequest request = new CreateIndexRequest("huang_index1");
        //执行请求,获得相应
        CreateIndexResponse response =
                client.indices().create(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }
    @Test
    void testExit() throws IOException {
        //获取索引
        GetIndexRequest request = new GetIndexRequest("huang_index1");
        boolean exists = client.indices().exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);

    }
    @Test
    void testDel() throws IOException {
        //删除索引
        DeleteIndexRequest request = new DeleteIndexRequest("huang_index");
        AcknowledgedResponse response =
                client.indices().delete(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }
}
 //添加文档
    @Test
    void testAddDocument() throws IOException {
        //创建对象
        User user = new User("name",18);
        //创建请求
        IndexRequest request = new IndexRequest("huang");
        request.id("1");
        request.timeout(TimeValue.timeValueSeconds(5));
        //将数据放入请求
        request.source(JSON.toJSONString(user), XContentType.JSON);
        //客户端发送请求
        IndexResponse response = client.index(request, RequestOptions.DEFAULT);
        System.out.println(response.toString());
    }
    //获取文档
    @Test
    void testExitDocument() throws IOException {
        GetRequest request = new GetRequest("huang", "1");
        boolean exists = client.exists(request, RequestOptions.DEFAULT);
        System.out.println(exists);
    }
    //获取文档信息
    @Test
    void testGetDoucent() throws IOException {
        GetRequest request = new GetRequest("huang", "1");
        GetResponse response = client.get(request, RequestOptions.DEFAULT);
        System.out.println(response.getSourceAsString());
        System.out.println(response);
    }
    //更新文档信息
    @Test
    void testUpdateDocument() throws IOException {
        UpdateRequest request = new UpdateRequest("huang", "1");
        request.timeout("1s");
        request.doc(JSON.toJSONString(new User("yao",3)),XContentType.JSON);
        UpdateResponse update = client.update(request, RequestOptions.DEFAULT);
        System.out.println(update);
    }
    //删除文档记录
    @Test
    void testDelDocument() throws IOException {
        DeleteRequest request = new DeleteRequest("huang", "1");
        request.timeout("1s");
        DeleteResponse response = client.delete(request, RequestOptions.DEFAULT);
        System.out.println(response);
    }
    //批量插入数据
    @Test
    void testManyD() throws IOException {
        BulkRequest request = new BulkRequest();
        request.timeout("10s");
        ArrayList<User> users = new ArrayList<>();
        users.add(new User("a",1));
        users.add(new User("b",1));
        users.add(new User("c",1));
        users.add(new User("d",1));
        for (int i = 0; i < users.size(); i++) {
            request.add(
                    new IndexRequest("huang")
                    .id(""+i)
                    .source(JSON.toJSONString(users.get(i)),XContentType.JSON)
            );
        }
        BulkResponse response = client.bulk(request, RequestOptions.DEFAULT);
        System.out.println(response.hasFailures());
    }
    //查询
    @Test
    void testSearch() throws IOException {
        SearchRequest request = new SearchRequest("huang");
        //构建搜索条件
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        //xxxxQueryBuilder构造查询条件
        TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("name", "huang");
        sourceBuilder.query(termQueryBuilder);
        sourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
        request.source(sourceBuilder);
        //执行
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        System.out.println(JSON.toJSONString(response.getHits()));
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值