首页 > 其他分享 >Elasticsearch

Elasticsearch

时间:2024-03-16 20:12:21浏览次数:23  
标签:String private Book Elasticsearch import new

Elasticsearch

Lucene,Solr,ElasticSearch 比较

Lucene, Solr, 和 Elasticsearch 是三个与搜索相关的开源项目,它们之间存在紧密的联系,但又有一些区别。以下是它们的比较:

  1. Lucene:
    • Lucene 是一个 Java 编写的全文检索引擎库,提供了强大的文本搜索和索引功能。
    • 它是一个基础库,提供了创建搜索应用所需的核心功能,包括索引构建、搜索和分析等。
    • Lucene 可以被其他项目作为底层搜索引擎来使用,但它本身并不提供完整的搜索应用解决方案。
  2. Solr:
    • Solr 是一个构建在 Lucene 之上的搜索平台,使用 Java 编写,提供了基于 HTTP 的 RESTful API。
    • Solr 提供了一系列的功能,包括分布式搜索、复杂查询、实时索引、缓存、扩展性等。
    • 它提供了方便的配置和管理工具,使得构建搜索应用更加容易。
    • Solr 适用于需要快速构建搜索应用的情况,尤其是对于企业级应用或者需要自定义搜索逻辑的场景。
  3. Elasticsearch:
    • Elasticsearch 也是基于 Lucene 构建的搜索引擎,但它不仅仅是一个搜索引擎,还是一个分布式文档存储和分析引擎。
    • Elasticsearch 提供了简单的 RESTful API,并且具有更广泛的用途,包括日志和事件分析、数据可视化、实时搜索等。
    • 它具有强大的分布式能力,支持水平扩展,可以处理大规模数据和高并发请求。
    • Elasticsearch 还提供了丰富的插件和生态系统,使得它更容易与其他工具和系统集成。

总的来说,Lucene 提供了搜索引擎的核心功能,Solr 是构建在 Lucene 之上的搜索平台,提供了更多的功能和方便的管理工具,而 Elasticsearch 则是一个更加广泛用途的分布式搜索和分析引擎,具有强大的分布式能力和丰富的生态系统。选择其中一个取决于你的需求和项目的规模。

本次演示以Elasticsearch为例

服务端

Docker Desktop 安装最新的Elasticsearch镜像并启动容器,注册端口:9200

http://localhost:9200/ 访问不了,学习演示的话,需要修改es配置文件elasticsearch.yml,关闭ssl安全访问权限控制,重启容器即可。

客户端

web界面安装

修改完成重启容器浏览器访问:http://localhost:9200/ 返回Elasticsearch 实例的详细信息如下:

{
  "name" : "00d7fda22075",
  "cluster_name" : "docker-cluster",
  "cluster_uuid" : "WeZtDCeNS0-Spxw_Uc79VQ",
  "version" : {
    "number" : "8.12.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "48a287ab9497e852de30327444b0809e55d46466",
    "build_date" : "2024-02-19T10:04:32.774273190Z",
    "build_snapshot" : false,
    "lucene_version" : "9.9.2",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

如果需要可视化界面需要安装chrome浏览器插件(简单易用,没有界面样式):Multi Elasticsearch Head

点击插件即可访问界面如下图所示:

也可以安装Kibana组件(功能强大)。

spring-boot项目使用示例

以maven spring-boot-starter-data-elasticsearch插件使用为例,添加spring-boot-starter-data-elasticsearch和elasticsearch-rest-high-level-client包(Rest API)。

maven配置添加如下包

	<!--spring整合elasticsearch包-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
		</dependency>
		<dependency>
			<groupId>org.elasticsearch.client</groupId>
			<artifactId>elasticsearch-rest-high-level-client</artifactId>
			<version>7.10.0</version>
		</dependency>

项目启动,构建初始化数据,初始化示例代码如下所示:

	@PostConstruct
		private void init() {
			// 创建文档
			Book book1 = new Book("1", "Java Programming Smith", "John Doe");
			Book book2 = new Book("2", "Spring Boot in Action", "Jane Smith");
			Book book3 = new Book("3", "Spring Boot es", "cao Smith");
			Book book4 = new Book("4", "Spring Boot mongodb Smith", "lili Smith");

			bookRepository.save(book1);
			bookRepository.save(book2);
			bookRepository.save(book3);
			bookRepository.save(book4);

			// 创建 Brand 对象
			Brand brand = new Brand();
			brand.setId("1");
			brand.setName("华为");
			brand.setCountry("中国");

			// 创建 Product 对象并设置嵌套的 Brand 对象
			Product product = new Product();
			product.setId("1");
			product.setName("手机");
			product.setPrice(1001.0);
			product.setBrand(brand);

			// 保存 Product 对象到 Elasticsearch 中
			elasticsearchOperations.save(product);
		}

其中Brand为Product的内嵌对象,JPA构建es索引代码如下:

package guru.springframework.domain;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.*;

@Data
@Document(indexName = "products")
public class Product {
    @Id
    private String id;
    private String name;
    private double price;

    @Field(type = FieldType.Nested)
    private Brand brand;

}

部分查询代码示例:

package guru.springframework.services;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class BookService {
    @Autowired
    private RestHighLevelClient elasticsearchClient;
    @Autowired
    private BookRepository bookRepository;
    private final String index = "library";

    public Page<Book> searchBooksByKeyword(String keyword, int page, int size) {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQuery = QueryBuilders.boolQuery()
                .should(QueryBuilders.matchQuery("title", keyword))
                .should(QueryBuilders.matchQuery("author", keyword));
        sourceBuilder.query(boolQuery);
        sourceBuilder.from(page * size);
        sourceBuilder.size(size);
        searchRequest.source(sourceBuilder);
        try {
            SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
            List<Book> books = extractBooksFromSearchResponse(response);
            long totalHits = response.getHits().getTotalHits().value;
            return new PageImpl<>(books, PageRequest.of(page, size), totalHits);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private List<Book> extractBooksFromSearchResponse(SearchResponse response) {
        List<Book> books = new ArrayList<>();
        for (SearchHit hit : response.getHits().getHits()) {
            Map<String, Object> sourceAsMap = hit.getSourceAsMap();
            String title = (String) sourceAsMap.get("title");
            String author = (String) sourceAsMap.get("author");
            // 构造Book对象
            Book book = new Book();
            book.setTitle(title);
            book.setAuthor(author);
            books.add(book);
        }
        return books;
    }

    public Page<Book> searchBooksByKeyword2(String keyword, int page, int size) {
       // return bookRepository.findByTitleContainingOrAuthorContaining(keyword,keyword,PageRequest.of(page, size));
        return bookRepository.findByTitleOrAuthorCustomQuery(keyword,PageRequest.of(page, size));
    }

}

package guru.springframework.services;;

import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ProductService {

    @Autowired
    private ProductRepository productRepository;
    @Autowired
    private RestHighLevelClient elasticsearchClient;

    private final String index = "products";

    @Autowired
    private ObjectMapper objectMapper;

    public Page<Product> getAllProducts(int pageNumber, int pageSize) {
        Pageable pageable = PageRequest.of(pageNumber, pageSize);
        return productRepository.findAll(pageable);
    }
    public Page<Product> searchProductsByBrandName(String brandName, int pageNumber, int pageSize) throws IOException {
        SearchRequest searchRequest = new SearchRequest(index);
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchQuery("brand.name", brandName));
        sourceBuilder.from(pageNumber * pageSize);
        sourceBuilder.size(pageSize);
        searchRequest.source(sourceBuilder);

        SearchResponse response = elasticsearchClient.search(searchRequest, RequestOptions.DEFAULT);
        List<Product> products = extractProductsFromSearchResponse(response);

        return new PageImpl<>(products, PageRequest.of(pageNumber, pageSize), response.getHits().getTotalHits().value);
    }

    private List<Product> extractProductsFromSearchResponse(SearchResponse response) {
        return Arrays.stream(response.getHits().getHits())
                .map(hit -> {
                    try {
                        return objectMapper.readValue(hit.getSourceAsString(), Product.class);
                    } catch (IOException e) {
                        throw new RuntimeException("Failed to parse search response", e);
                    }
                })
                .collect(Collectors.toList());
    }

}

  • RestHighLevelClient 提供一些接口,可以通过抽象方式构建查询等一些操作。面向对象编程,但是写法反而更麻烦,代码更冗余。
  • JPA方式,有了ChatGPT后,其实JPA写法更快,就一行代码,之前这种手写查询语句的方法不好写或者不好维护,现在不用维护,直接扔给ChatGPT,生成查询语句。在BookRepository查询方法上添加@Query注解查询语句。BookRepository代码如下所示:
package guru.springframework.repositories;

import guru.springframework.domain.Book;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface BookRepository extends ElasticsearchRepository<Book, String> {
    Page<Book> findByTitleContainingOrAuthorContaining(String title, String author, Pageable pageable);
    @Query("{\"bool\": {\"should\": [{\"match\": {\"title\": \"?0\"}}, {\"match\": {\"author\": \"?0\"}}]}}")
    Page<Book> findByTitleOrAuthorCustomQuery(String keyword, Pageable pageable);
}

数据查询结果格式如下图所示:

项目源码及调试

Github下载地址:https://github.com/caohuajin/Elasticsearch

ApiPost在线接口:https://console-docs.apipost.cn/preview/d900735c0fcb6588/d644ecf613c746f4

标签:String,private,Book,Elasticsearch,import,new
From: https://www.cnblogs.com/caohuajin/p/18077508

相关文章

  • 分布式搜索elasticsearch(1)
    1.初识elasticsearch1.1.了解ES1.1.1.elasticsearch的作用elasticsearch是一款非常强大的开源搜索引擎,具备非常多强大功能,可以帮助我们从海量数据中快速找到需要的内容例如:在GitHub搜索代码在电商网站搜索商品 在百度搜索答案在打车软件搜索附近的车1.1.2.ELK技......
  • Elasticsearch 基础-1
    Elasticsearch是一个基于Lucene的搜索服务器。它提供了一个分布式多用户能力的全文搜索引孳,基于RESTfulweb接口。功能:分布式的搜索引擎和数据分析引擎全文检索(like),结构化检索(a=1),数据分析(count/groupby)对海量数据进行近实时的处理(秒级)特点:可拓展性:大型分布式集群(......
  • Elasticsearch - Docker安装Elasticsearch8.12.2
    前言最近在学习ES,所以需要在服务器上装一个单节点的ES服务器环境:centos7.9安装下载镜像目前最新版本是8.12.2dockerpulldocker.elastic.co/elasticsearch/elasticsearch:8.12.2创建配置新增配置文件elasticsearch.ymlhttp.host:0.0.0.0http.cors.enabled:true......
  • 数据库不应放在容器中?- B站Kubernetes有状态服务实践(Elasticsearch/Clickhouse)
    本期作者前言云原生时代下,Kubernetes已成为容器技术的事实标准, 使得基础设施领域应用下自动化运维管理与编排成为可能。对于无状态服务而言, 业界早已落地数套成熟且较完美的解决方案。可对于有状态的服务, 方案的复杂度就以几何倍数增长, 例如分布式应用多个实例间的依......
  • Elasticsearch:调整搜索速度
    在我之前的文章“Elasticsearch:如何提高查询性能”及“Elasticsearch:提升Elasticsearch性能”里,我详细描述了如何提高搜索的性能。在今天的文章里,我从另外一个视角来描述如何调整搜索的速度。希望对大家有所帮助!为文件系统缓存提供内存Elasticsearch严重依赖文件系......
  • ElasticSearch高可用部署
    简单说明我们在部署ElasticSearch高可用集群时,要规划好集群的规模,每个节点的职责,规划好后续的水平扩展方案,再进行部署。核心概念Cluster:集群,由一个或多个Elasticsearch节点组成。Node:节点,组成Elasticsearch集群的服务单元,同一个集群内节点的名字不能重复。通常在一个节点......
  • Rancher怎么设置把日志发送给elasticsearch
    搭建elascsearch集群不详述配置日志发送打开日志Rancher配置日志发送其实时在node启用了Daemonset使用fluentd进行日志收集#kubectlgetdaemonset-ncattle-loggingNAMEDESIREDCURRENTREADYUP-TO-DATEAVAILABLEN......
  • 什么是Elasticsearch?
     介绍  当人们问“什么是Elasticsearch?”时,有些人可能会回答说它是“一个索引”,“一个搜索引擎”,“分析数据库”,“一个大数据解决方案”,“它快速且可扩展”,或者“它有点像谷歌”。根据您对这项技术的熟悉程度,这些答案可能会使您更接近啊哈时刻,或者让您进一步困惑。但事......
  • Elasticsearch探秘:原理剖析、高级运用与实战经验【文末送书-37】
    文章目录Elasticsearch探秘:原理剖析、高级运用与实战经验进阶使用方法数据建模与映射实战工程案例索引阻塞的种类什么时候使用阻塞?一本书讲透Elasticsearch:原理、进阶与工程实践【文末送书-37】Elasticsearch探秘:原理剖析、高级运用与实战经验Elasticsearch作为一个......
  • Elasticsearch 如何保证写入过程中不丢失数据的
    丢失数据的本质在本文开始前,首先明白一个点,平时我们说的组件数据不丢失究竟是在指什么,如果你往ES写入数据,ES返回给你写入错误,这个不算数据丢失。如果你往ES写入数据,ES返回给你成功,但是后续因为ES节点重启或宕机导致写入的数据不见了,这个才叫数据丢失。简而言之,丢失数据的本质是E......