Hibernate + Lucene - 通配符搜索返回空结果
Hibernate + Lucene - wildard search returning empty result
我写了一篇关于通过通配符搜索数据库 table 的漂亮 Hibernate 搜索的文章。
所以我把它添加到我的 pom.xml:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>5.5.4.Final</version>
</dependency>
设置目录提供程序:
properties.put("hibernate.search.default.directory_provider", "ram");
并在我的实体上定义索引以供搜索机制使用:
@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 脚本数据库手动加载 table - CUSTOM_ENTITY:
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();
但是每次结果集合都是空的。你知道我是否错过了任何一步吗?我应该使用 Hibernate API 而不是 SQL 脚本加载数据吗?
编辑
在 运行ning 查询之前我手动索引数据:
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 加载数据,则需要使用 Mass indexer 手动索引数据。参见 https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#search-batchindex-massindexer。
如果您使用的是 Hibernate API,它们将被自动编入索引。
搜索完having indexed所有实体后,需要用?
或*
进行正确的通配查询。字符 ?
表示单个字符,*
表示任何字符序列:
假设您有以下 table :
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();
问题已解决。问题与骆驼案例有关 "search string"。
我注意到即使我将值存储在数据库中,例如:
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();
一切正常。我还不知道为什么,但它解决了这个问题。
感谢您的宝贵时间和帮助。
我写了一篇关于通过通配符搜索数据库 table 的漂亮 Hibernate 搜索的文章。
所以我把它添加到我的 pom.xml:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-search-orm</artifactId>
<version>5.5.4.Final</version>
</dependency>
设置目录提供程序:
properties.put("hibernate.search.default.directory_provider", "ram");
并在我的实体上定义索引以供搜索机制使用:
@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 脚本数据库手动加载 table - CUSTOM_ENTITY:
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();
但是每次结果集合都是空的。你知道我是否错过了任何一步吗?我应该使用 Hibernate API 而不是 SQL 脚本加载数据吗?
编辑
在 运行ning 查询之前我手动索引数据:
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 加载数据,则需要使用 Mass indexer 手动索引数据。参见 https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#search-batchindex-massindexer。
如果您使用的是 Hibernate API,它们将被自动编入索引。
搜索完having indexed所有实体后,需要用?
或*
进行正确的通配查询。字符 ?
表示单个字符,*
表示任何字符序列:
假设您有以下 table :
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();
问题已解决。问题与骆驼案例有关 "search string"。
我注意到即使我将值存储在数据库中,例如:
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();
一切正常。我还不知道为什么,但它解决了这个问题。
感谢您的宝贵时间和帮助。