Java 冬眠+;Lucene-wildard搜索返回空结果

Java 冬眠+;Lucene-wildard搜索返回空结果,java,hibernate,lucene,hibernate-search,Java,Hibernate,Lucene,Hibernate Search,我写了一篇关于使用通配符搜索数据库表的Hibernate搜索的文章 因此,我将其添加到pom.xml中: <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-search-orm</artifactId> <version>5.5.4.Final</version>

我写了一篇关于使用通配符搜索数据库表的Hibernate搜索的文章

因此,我将其添加到pom.xml中:

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-search-orm</artifactId>
        <version>5.5.4.Final</version>
    </dependency>
并在我的实体上定义了索引,以便在搜索机制中可见:

@Entity
@Table(name = "CUSTOM_ENTITY")
@Audited
@Indexed
public class CustomEntity implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")
    @DocumentId
    private Long id;

    @Column(name = "NAME1", nullable = false)
    @NotEmpty
    @Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
    private String name1;

    @Column(name = "NAME2", nullable = false)
    @NotEmpty
    @Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
    private String name2;

    @Column(name = "NAME3", nullable = false)
    @NotEmpty
    @Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
    private String name3;

    // ...
}
然后,我从SQL脚本数据库表-自定义实体手动加载:

ID |NAME1 |NAME2 |NAME3 |
-------------------------
1  |Test1 |Test1 |Test1 |
2  |Test2 |Test2 |Test2 |
3  |Test3 |Test2 |Test2 |
并在我的存储库中运行代码:

FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);

QueryBuilder qBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(CustomEntity.class).get();

Query luceneQuery = qBuilder.keyword().wildcard().onFields("name1", "name2", "name3").matching("Test").createQuery();
// Query luceneQuery = qBuilder.keyword().wildcard().onFields("name1", "name2", "name3").matching("Test*").createQuery();
// Query luceneQuery = qBuilder.keyword().wildcard().onFields("name1", "name2", "name3").matching("Test%").createQuery();

List test = fullTextEntityManager.createFullTextQuery(luceneQuery, CustomEntity.class).getResultList();
但是,每次结果集合都为空。你知道我有没有错过任何一步吗?我应该用HibernateAPI而不是SQL脚本加载数据吗


编辑

在运行查询之前,我正在手动索引数据:

FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
try {
    fullTextEntityManager.createIndexer().startAndWait();
} catch (InterruptedException e) {
    e.printStackTrace();
}
QueryBuilder qBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity(CustomEntity.class).get();

Query luceneQuery = qBuilder.keyword().wildcard().onFields("name1", "name2", "name3").matching("Test").createQuery();
// Query luceneQuery = qBuilder.keyword().wildcard().onFields("name1", "name2", "name3").matching("Test*").createQuery();
// Query luceneQuery = qBuilder.keyword().wildcard().onFields("name1", "name2", "name3").matching("Test%").createQuery();

List test = fullTextEntityManager.createFullTextQuery(luceneQuery, CustomEntity.class).getResultList();
结果还是一样


谢谢您的帮助。

如果您使用SQL加载数据,则需要使用海量索引器手动为数据编制索引。看

如果您使用的是Hibernate API,它们将自动编制索引。

在搜索所有实体之后,您需要使用
*
进行正确的通配符查询。字符
表示单个字符,
*
表示任何字符序列:

假设您有下表:

ID | NAME1  | NAME2  | NAME3  |
-------------------------------
1  | test1  | test1  | test1  |
2  | test2  | test2  | test2  |
3  | test3  | test3  | test3  |
4  | test4A | test4B | test4C |
然后使用
您将获得3个结果,使用
*
您将获得4个结果

Query luceneQuery = qBuilder.keyword()
    .wildcard()
    .onFields("name1", "name2", "name3")
    .matching("test?")  // return {1, 2, 3}
//  .matching("test*")  // return {1, 2, 3, 4}
//  .matching("test")   // return {}
    .createQuery();

问题解决了。问题与驼峰案例“搜索字符串”有关

我注意到,即使我在数据库中存储了如下值:

ID |NAME1 |NAME2 |NAME3 |
-------------------------
1  |Test1 |Test1 |Test1 |
2  |Test2 |Test2 |Test2 |
3  |Test3 |Test2 |Test2 |
Lucene无法通过字符串测试进行搜索*:

Query luceneQuery = qBuilder.keyword().wildcard().onFields("name1", "name2", "name3").matching("Test*").createQuery();
当我将查询更改为以下内容时:

Query luceneQuery = qBuilder.keyword().wildcard().onFields("name1", "name2", "name3").matching("test*").createQuery();
一切正常。我还不知道为什么,但它解决了这个问题


谢谢您的时间和帮助。

您以前做过这些吗?您的注释看起来不错,它们应该自动检测插入的新实体并为它们编制索引。但是,对于现有数据,您需要启动mass indexer来重建索引。还要记住,当您使用“ram”目录时,索引不会持久化。是否在索引和查询之间重新启动Hibernate SessionFactory(或JPA EntityManager)?
Query luceneQuery = qBuilder.keyword().wildcard().onFields("name1", "name2", "name3").matching("test*").createQuery();