亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在Spring Boot中使用ElasticSearch實現一個搜索引擎

發布時間:2021-04-08 16:04:22 來源:億速云 閱讀:204 作者:Leah 欄目:編程語言

這篇文章將為大家詳細講解有關怎么在Spring Boot中使用ElasticSearch實現一個搜索引擎,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。

Elastic Search是一個開源的,分布式,實時搜索和分析引擎。Spring Boot為Elasticsearch及Spring Data Elasticsearch提供的基于它的抽象提供了基本的配置。Spring Boot提供了一個用于聚集依賴的spring-boot-starter-data-elasticsearch 'StarterPOM'。

ElasticSearch作為搜索引擎,我們需要解決2大問題:

1,  如何將被搜索的數據在ES上創建反向索引
2,  Java代碼如何與ES交互

其中第一個大問題又分為兩個小問題

1.1,如何初始化已有的數據
1.2,如何同步增量數據

第二個大問題也有兩種集成方式

2.1 Spring Data 9300端口集成
2.2 Restful API 9200端口集成

本篇先解決第二大問題。

第一種方式,利用RestAPI方式,也叫Jest方式:

示例代碼:https://github.com/yejingtao/forblog/tree/master/demo-jest-elasticsearch

Pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
 <modelVersion>4.0.0</modelVersion> 
 
 <groupId>yejingtao.demo.springcloud</groupId> 
 <artifactId>demo-jest-elasticsearch</artifactId> 
 <version>0.0.1-SNAPSHOT</version> 
 <packaging>jar</packaging> 
 
 <name>demo-jest-elasticsearch</name> 
 <url>http://maven.apache.org</url> 
 
 <properties> 
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
 </properties> 
  
 <parent> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-parent</artifactId> 
    <version>1.5.6.RELEASE</version> 
  </parent> 
   
  <dependencies> 
    <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
    <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-elasticsearch</artifactId> 
    </dependency> 
    <dependency> 
      <groupId>io.searchbox</groupId> 
      <artifactId>jest</artifactId> 
    </dependency> 
    <dependency> 
      <groupId>net.java.dev.jna</groupId> 
      <artifactId>jna</artifactId> 
    </dependency> 
  </dependencies> 
</project>

Application.yml:

server: 
 port: 7081 
 
spring: 
 elasticsearch: 
  jest: 
   uris: 
   - http://192.168.226.133:9200 
   read-timeout: 5000

注意這里是9200端口

主程序:最簡單的Spring boot啟動程序:

@SpringBootApplication 
public class ESApplication { 
 
  public static void main(String[] args) { 
    SpringApplication.run(ESApplication.class); 
  } 
}

定義好ES中的實體類和對ES操作的接口:

public class Entity implements Serializable{ 
 
  private static final long serialVersionUID = -763638353551774166L; 
   
  public static final String INDEX_NAME = "index_entity"; 
   
  public static final String TYPE = "tstype"; 
 
  private Long id; 
   
  private String name; 
   
  public Entity() { 
    super(); 
  } 
   
  public Entity(Long id, String name) { 
    this.id = id; 
    this.name = name; 
  } 
 
  public Long getId() { 
    return id; 
  } 
 
  public void setId(Long id) { 
    this.id = id; 
  } 
 
  public String getName() { 
    return name; 
  } 
 
  public void setName(String name) { 
    this.name = name; 
  } 
   
   
}
public interface CityESService { 
   
  void saveEntity(Entity entity); 
   
  void saveEntity(List<Entity> entityList); 
   
  List<Entity> searchEntity(String searchContent); 
}

接口實現:

@Service 
public class CityESServiceImpl implements CityESService{ 
   
  private static final Logger LOGGER = LoggerFactory.getLogger(CityESServiceImpl.class); 
   
  @Autowired 
  private JestClient jestClient; 
   
  @Override 
  public void saveEntity(Entity entity) { 
    Index index = new Index.Builder(entity).index(Entity.INDEX_NAME).type(Entity.TYPE).build(); 
    try { 
      jestClient.execute(index); 
      LOGGER.info("ES 插入完成"); 
    } catch (IOException e) { 
      e.printStackTrace(); 
      LOGGER.error(e.getMessage()); 
    } 
  } 
   
   
  /** 
   * 批量保存內容到ES 
   */ 
  @Override 
  public void saveEntity(List<Entity> entityList) { 
    Bulk.Builder bulk = new Bulk.Builder(); 
    for(Entity entity : entityList) { 
      Index index = new Index.Builder(entity).index(Entity.INDEX_NAME).type(Entity.TYPE).build(); 
      bulk.addAction(index); 
    }     
    try { 
      jestClient.execute(bulk.build()); 
      LOGGER.info("ES 插入完成"); 
    } catch (IOException e) { 
      e.printStackTrace(); 
      LOGGER.error(e.getMessage()); 
    } 
  } 
   
  /** 
   * 在ES中搜索內容 
   */ 
  @Override 
  public List<Entity> searchEntity(String searchContent){ 
    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
    //searchSourceBuilder.query(QueryBuilders.queryStringQuery(searchContent)); 
    //searchSourceBuilder.field("name"); 
    searchSourceBuilder.query(QueryBuilders.matchQuery("name",searchContent)); 
    Search search = new Search.Builder(searchSourceBuilder.toString()) 
        .addIndex(Entity.INDEX_NAME).addType(Entity.TYPE).build(); 
    try { 
      JestResult result = jestClient.execute(search); 
      return result.getSourceAsObjectList(Entity.class); 
    } catch (IOException e) { 
      LOGGER.error(e.getMessage()); 
      e.printStackTrace(); 
    } 
    return null;     
  } 
}

這里插入數據的方式給了兩種,一種是單次API直接插入,一種是利用ES的bulk批量插入。

做一個controller方面我們測試:

啟動后在瀏覽器中請求http://localhost:7081/entityController/search?name=%E4%BA%BA%E6%89%8B%E4%BA%95

得到結果:

怎么在Spring Boot中使用ElasticSearch實現一個搜索引擎

這里只返回了9條記錄,而理論上ES默認的size是10,應該不是分頁的問題,而是只能檢索出9條匹配記錄,用Kibana連上相同的搜索確認下:

怎么在Spring Boot中使用ElasticSearch實現一個搜索引擎

這里用的是standard分詞方式,將每個中文都作為了一個term,凡是包含“人”“手”“井”的都被搜索了出來,只是評分不同,如果想支持只能中文索引需要依賴ik插件

OK,RestFul方式對ElasticSearch的檢索已經搞定了,更多的擴展可以慢慢研究下QueryBuilders里的源碼和批注。

第二種方式,利用Spring Data客戶端方式:

事先說明此方式有個弊端,讓我掉了坑里好久才爬上來,Spring Data ElasticSearch必須與ElasticSearch版本相匹配,否則在對接時ES端會報版本不匹配錯誤,例如我ES是5.6.1版本,Spring boot是1.5.6版本,錯誤如下:

為解決這個問題我查找了一些資料,Spring Data與elasticsearch版本對應關系如下:

spring data elasticsearch

elasticsearch

3.0.0.RC2

5.5.0

3.0.0.M4

5.4.0

2.0.4.RELEASE

2.4.0

2.0.0.RELEASE

2.2.0

1.4.0.M1

1.7.3

1.3.0.RELEASE

1.5.2

1.2.0.RELEASE

1.4.4

1.1.0.RELEASE

1.3.2

1.0.0.RELEASE

1.1.1

而我用的Spring Boot 1.5.6版本對應的Spring Data ElasticSearch是2.1.6版本,不支持5.X的ES,所以報錯。到本博文撰寫為止,Spring Boot的RELEASE版本最新的是1.5.8,對應的Spring Data ElasticSearch是2.1.8,仍不支持5.X的ES,所以如果一定要使用Java客戶端方式集成ES只能放棄Spring Boot直接使用Spring Data和Spring MVC,或者降低ES的版本使之與Spring boot匹配。

示例代碼:https://github.com/yejingtao/forblog/tree/master/demo-data-elasticsearch

pom.xml依賴:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 
 <modelVersion>4.0.0</modelVersion> 
 
 <groupId>yejingtao.demo.springcloud</groupId> 
 <artifactId>demo-data-elasticsearch</artifactId> 
 <version>0.0.1-SNAPSHOT</version> 
 <packaging>jar</packaging> 
 
 <name>demo-data-elasticsearch</name> 
 <url>http://maven.apache.org</url> 
 
 <properties> 
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
 </properties> 
  
 <parent> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-parent</artifactId> 
    <version>1.5.8.RELEASE</version> 
  </parent> 
   
  <dependencies> 
    <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
    <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-elasticsearch</artifactId> 
    </dependency> 
  </dependencies> 
</project>

不再引用Jest。

application.yml:

server: 
 port: 7081 
 
spring: 
 data: 
  elasticsearch: 
   cluster-nodes: 192.168.226.133:9300 
   cluster-name: my-es 
   repositories: 
    enabled: true

注意這里是9300端口

Controller、主程序、Service接口同Jest項目不變,不再羅列

實體類稍作變化,指定ES中的index和type:

@Document(indexName="index_entity", type="tstype")

多一個Repository接口,無需實現類,spring data標準用法:

/** 
 * Entity ES操作類 
 * @author yejingtao 
 * 
 */ 
public interface EntityRepository extends ElasticsearchRepository<Entity,Long>{ 
 
}

Service實現類與Jest的天壤之別了,從語法上可以看出更像是對數據庫層的操作:

@Service 
public class CityESServiceImpl implements CityESService{ 
   
  private static final Logger LOGGER = LoggerFactory.getLogger(CityESServiceImpl.class); 
   
  int PAGE_SIZE = 15; //默認分頁大小 
   
  int PAGE_NUMBER = 0; //默認當前分頁 
   
  String SCORE_MODE_SUM = "sum"; //權重分求和模式 
   
  Float MIN_SCORE = 10.0F; //由于無相關性的分值默認為1, 設置權重分最小值為10 
   
  @Autowired 
  EntityRepository entityRepository; 
   
  /** 
   * 保存內容到ES 
   */ 
  @Override 
  public Long saveEntity(Entity entity) { 
    Entity entityResult = entityRepository.save(entity); 
    return entityResult.getId(); 
  } 
   
  /** 
   * 在ES中搜索內容 
   */ 
  @Override 
  public List<Entity> searchEntity(int pageNumber, int pageSize, String searchContent){ 
    if(pageSize==0) { 
      pageSize = PAGE_SIZE; 
    } 
    if(pageNumber<0) { 
      pageNumber = PAGE_NUMBER; 
    } 
     
    SearchQuery searchQuery = getEntitySearchQuery(pageNumber,pageSize,searchContent); 
     
    LOGGER.info("\n searchCity: searchContent [" + searchContent + "] \n DSL = \n "  
        + searchQuery.getQuery().toString()); 
 
     
    Page<Entity> cityPage = entityRepository.search(searchQuery); 
    return cityPage.getContent(); 
  } 
   
  /** 
   * 組裝搜索Query對象 
   * @param pageNumber 
   * @param pageSize 
   * @param searchContent 
   * @return 
   */ 
  private SearchQuery getEntitySearchQuery(int pageNumber, int pageSize, String searchContent) { 
    FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery() 
        .add(QueryBuilders.matchPhraseQuery("name", searchContent), 
            ScoreFunctionBuilders.weightFactorFunction(1000)) 
        //.add(QueryBuilders.matchPhraseQuery("other", searchContent), 
            //ScoreFunctionBuilders.weightFactorFunction(1000)) 
        .scoreMode(SCORE_MODE_SUM).setMinScore(MIN_SCORE); 
    //設置分頁,否則只能按照ES默認的分頁給 
    Pageable pageable = new PageRequest(pageNumber, pageSize); 
    return new NativeSearchQueryBuilder().withPageable(pageable).withQuery(functionScoreQueryBuilder).build(); 
  } 
   
}

關于怎么在Spring Boot中使用ElasticSearch實現一個搜索引擎就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

胶州市| 宣城市| 宁安市| 广河县| 曲靖市| 南华县| 胶南市| 高阳县| 华宁县| 鹰潭市| 镇雄县| 大丰市| 玛多县| 松原市| 枞阳县| 沾益县| 盐津县| 澄城县| 贡觉县| 阿克陶县| 鄂伦春自治旗| 龙口市| 池州市| 余干县| 大宁县| 二连浩特市| 含山县| 微博| 工布江达县| 怀安县| 买车| 拉孜县| 商丘市| 句容市| 新兴县| 长宁区| 察雅县| 东辽县| 宜良县| 鄂托克旗| 新宁县|