如何在Spring Boot中使用JPA + MySQL实现全文搜索

10
public class Product {

    private Long id;    

    private String name;

    private String description;

}

有没有办法使用JpaRepository实现对Product类的描述进行全文搜索?
1个回答

17
你可以使用Hibernate Search,这是一个插入到Hibernate ORM中的库,可以在你将实体发送到数据库时,即时地将它们索引到文件系统上的Lucene索引中。请参阅入门指南
编辑:现在Hibernate Search也支持使用Elasticsearch作为后端;它会自动在Elasticsearch或本地Lucene索引中复制您数据库的一部分,具体取决于您选择的方式。)
查询Lucene/Elasticsearch索引与查询数据库有所不同,因此您无法像通常那样使用HQL或Criteria。Hibernate Search提供了自己的查询DSL。
如果您想在存储库中使用自动生成的方法实现,可以依赖Snowdrop,它是一个Hibernate Search/Spring Data集成,但它已经有一段时间没有更新了。
你最好的选择可能是在存储库接口中定义查询方法,然后使用Hibernate Search API自己实现它们。这真的不是很复杂,通常建议使用除了最明显的查询之外的所有查询。请参阅Spring Data JPA文档

基本上,您将拥有如下代码片段。请记住,在此之前需要重新索引数据库!有关更多信息,请参见入门指南

使用 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进行OR操作:

@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();
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接