【问题标题】:How to implement full text search in Spring Boot with JPA + MySQL如何使用 JPA + MySQL 在 Spring Boot 中实现全文搜索
【发布时间】:2020-01-01 03:02:08
【问题描述】:
public class Product {

    private Long id;    

    private String name;

    private String description;

}

有没有办法使用 JpaRepository 实现对 Product 类的描述的全文搜索?

【问题讨论】:

    标签: hibernate spring-boot spring-data-jpa full-text-search hibernate-search


    【解决方案1】:

    您可以使用Hibernate Search,这是一个插入 Hibernate ORM 的库,可在您将实体发送到数据库时即时将它们索引到文件系统上的 Lucene 索引中。请参阅Getting started guide

    编辑:如今 Hibernate Search 还支持使用 Elasticsearch 作为后端;它会自动在 Elasticsearch 或本地 Lucene 索引中复制您的数据库的一部分,无论您选择哪个。)

    查询 Lucene/Elasticsearch 索引与查询数据库有点不同,因此您不能像通常那样使用 HQL 或 Criteria。 Hibernate Search 提供了自己的查询 DSL。

    如果您想在您的存储库中使用自动生成的方法实现,您可以依赖 Snowdrop,这是一个 Hibernate Search / Spring Data 集成,但它已经有一段时间没有更新了。

    您最好的选择可能是在您的存储库接口中定义查询方法,然后使用 Hibernate Search API 自己实现它们。它真的没有那么复杂,除了最明显的查询之外,它通常被推荐用于所有查询。见the Spring Data JPA documentation

    基本上你会得到类似下面的 sn-p 的东西。请记住,您需要在此工作之前重新索引您的数据库!请参阅getting started guide 了解更多信息。

    使用 Hibernate Search 6+:

    @Indexed // Add this
    public class Product {
    
        private Long id;    
    
        @FullTextField // And this
        private String name;
    
        @FullTextField // And this
        private String description;
    
    }
    
    public interface ProductRepository extends CrudRepository<Product, Long>, CustomizedProductRepository {
      // Declare automatically generated methods here
    }
    
    
    public interface CustomizedProductRepository {
      List<Product> search(String terms, int limit, int offset);
    }
    
    
    
    public class CustomizedProductRepositoryImpl implements CustomizedProductRepository {
    
      @PersistenceContext
      private EntityManager em;
    
      @Override
      public List<Product> search(String terms, int limit, int offset) {
        return Search.session(em).search(Product.class)
                .where(f -> f.match()
                        .fields("name", "description")
                        .matching(terms))
                .fetchHits(offset, limit);
      }
    }
    

    或与 Hibernate Search 5:

    @Indexed // Add this
    public class Product {
    
        private Long id;    
    
        @Field // And this
        private String name;
    
        @Field // And this
        private String description;
    
    }
    
    public interface ProductRepository extends CrudRepository<Product, Long>, CustomizedProductRepository {
      // Declare automatically generated methods here
    }
    
    
    public interface CustomizedProductRepository {
      List<Product> search(String terms, int limit, int offset);
    }
    
    
    
    public class CustomizedProductRepositoryImpl implements CustomizedProductRepository {
    
      @PersistenceContext
      private EntityManager em;
    
      @Override
      public List<Product> search(String terms, int limit, int offset) {
        FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
    
        QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory()
            .buildQueryBuilder().forEntity(Product.class).get();
        org.apache.lucene.search.Query luceneQuery = queryBuilder
            .keyword()
            .onFields("name", "description")
            .matching(terms)
            .createQuery();
    
        // wrap Lucene query in a javax.persistence.Query
        javax.persistence.Query jpaQuery =
            fullTextEntityManager.createFullTextQuery(luceneQuery, Product.class);
    
        jpaQuery.setMaxResults(limit);
        jpaQuery.setFirstResult(offset);
    
        // execute search
        return jpaQuery.getResultList();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-18
      • 2023-04-04
      • 1970-01-01
      • 2019-10-28
      • 1970-01-01
      • 1970-01-01
      • 2018-11-11
      相关资源
      最近更新 更多