假设我有一个应用程序,有许多不同的实体,它们之间没有关系。
我想创建一个搜索,查询所有这些,但返回一个统一的类型,即:
class SearchResult {
String stype;
String title;
String teaser;
}
@Indexed(index = "idx_search")
class Book {
@Field(name = "stype", analyze = ...)
final String stype = "BOOK";
@Field(name = "title", analyze = ...)
String bookTitle;
@Field(name = "teaser", analyze = ...)
String bookBlurb ;
}
@Indexed(index = "idx_search")
class Person{
@Field(name = "stype", analyze = ...)
final String stype = "PERSON";
@Field(name = "title", analyze = ...)
String fullname;
@Field(name = "teaser", analyze = ...)
String profileIntroText;
}
@Indexed(index = "idx_search")
class Location{
@Field(name = "stype", analyze = ...)
final String stype = "LOCATION";
@Field(name = "title", analyze = ...)
String streetPcAndCity;
@Field(name = "teaser", analyze = ...)
String wikiIntoText;
}
SearchResult[stype: PERSON, title: Spongebob, teaser: A funny sponge]
SearchResult[stype: BOOK, title: Clean Architecture , teaser: A Craftsmans Guide to Software...]
SearchResult[stype: PERSON, title: Patric, teaser: A funny seastar]
SearchResult[stype: LOCATION, title: Hannover, teaser: A city in Germany]
final QueryBuilder queryBuilder = fullTextEntityManager
.getSearchFactory()
.buildQueryBuilder()
.forEntity(SearchResult.class)
.get();
...
HSearch000331:无法为既未配置也未配置任何子类型的类型“SearchResult”生成查询。
你认为有办法让它起作用吗?
注意,您不需要将每个类型分配给相同的索引;Hibernate Search完全能够在单个查询中搜索多个索引。性能可能是相同的(无论如何,Lucene索引通常被分成多个区段)。
话虽如此,假设SearchResult
中有一个构造函数,下面是如何实现的:
class SearchResult {
String stype;
String title;
String teaser;
public SearchResult(String stype, String title, String teaser) {
this.stype = stype;
this.title = title;
this.teaser = teaser;
}
}
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager( entityManager);
final QueryBuilder queryBuilder = fullTextEntityManager
.getSearchFactory()
.buildQueryBuilder()
.forEntity(Book.class)
.get();
Query luceneQuery = ...;
FullTextQuery query = fullTextEntityManager.createFullTextQuery(query, Book.class, Person.class, Location.class);
query.setProjection("stype", "title", "teaser");
query.setMaxResults(20);
List<Object[]> arrayResults = query.list();
List<SearchResult> hits = new ArrayList<>();
for (Object[] array : arrayResults) {
hits.add(new SearchResult((String) array[0], (String) array[1], (String) array[2]);
}
还要注意,如果升级到Hibernate Search6,这可能会明显减少尴尬。
@Indexed
class Book {
@KeywordField(name = "stype")
@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.NO)
final String stype = "BOOK";
@FullTextField(name = "title", analyzer = ...)
String bookTitle;
@FullTextField(name = "teaser", analyzer = ...)
String bookBlurb ;
}
@Indexed
class Person{
@KeywordField(name = "stype")
@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.NO)
final String stype = "PERSON";
@FullTextField(name = "title", analyzer = ...)
String fullname;
@FullTextField(name = "teaser", analyzer = ...)
String profileIntroText;
}
@Indexed
class Location{
@KeywordField(name = "stype")
@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.NO)
final String stype = "LOCATION";
@FullTextField(name = "title", analyzer = ...)
String streetPcAndCity;
@FullTextField(name = "teaser", analyzer = ...)
String wikiIntoText;
}
List<SearchResult> hits = Search.session(entityManager)
.search(Book.class, Person.class, Location.class)
.select(f -> f.composite(
SearchResult::new,
f.field("stype", String.class),
f.field("title", String.class),
f.field("teaser", String.class)))
.where(f -> ...)
.fetchHits( 20 );
interface Searchable {
@KeywordField(analyzer = ...)
String getStype();
@FullTextField(analyzer = ...)
String getTitle();
@FullTextField(analyzer = ...)
String getTeaser();
}
@Indexed
class Book implements Searchable {
String bookTitle;
String bookBlurb;
@Override
@javax.persistence.Transient
@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.NO)
String getStype() {
return "BOOK";
}
@Override
@javax.persistence.Transient
@IndexingDependency(derivedFrom = @ObjectPath(
@PropertyValue(propertyName = "bookTitle")
))
String getTitle() {
return bookTitle;
}
@Override
@javax.persistence.Transient
@IndexingDependency(derivedFrom = @ObjectPath(
@PropertyValue(propertyName = "bookTitle")
))
String getTeaser() {
return bookBlurb;
}
}
@Indexed
class Person implements Searchable {
String fullname;
String profileIntroText;
@Override
@javax.persistence.Transient
@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.NO)
String getStype() {
return "PERSON";
}
@Override
@javax.persistence.Transient
@IndexingDependency(derivedFrom = @ObjectPath(
@PropertyValue(propertyName = "bookTitle")
))
String getTitle() {
return bookTitle;
}
@Override
@javax.persistence.Transient
@IndexingDependency(derivedFrom = @ObjectPath(
@PropertyValue(propertyName = "bookTitle")
))
String getTeaser() {
return bookBlurb;
}
}
@Indexed
class Location implements Searchable {
String streetPcAndCity;
String wikiIntoText;
@Override
@javax.persistence.Transient
@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.NO)
String getStype() {
return "LOCATION";
}
@Override
@javax.persistence.Transient
@IndexingDependency(derivedFrom = @ObjectPath(
@PropertyValue(propertyName = "streetPcAndCity")
))
String getTitle() {
return streetPcAndCity;
}
@Override
@javax.persistence.Transient
@IndexingDependency(derivedFrom = @ObjectPath(
@PropertyValue(propertyName = "wikiIntoText")
))
String getTeaser() {
return wikiIntoText;
}
}
List<SearchResult> hits = Search.session(entityManager)
.search(Searchable.class)
.select(f -> f.composite(
SearchResult::new,
f.field("stype", String.class),
f.field("title", String.class),
f.field("teaser", String.class)))
.where(f -> ...)
.fetchHits( 20 );
或者,您可以直接加载实体:
List<Searchable> hits = Search.session(entityManager)
.search(Searchable.class)
.where(f -> ...)
.fetchHits( 20 );
for (Searchable hit : hits) {
String stype = hit.getStype();
String title = hit.getTitle();
String teaser = hit.getTeaser();
if ( hit instanceof Book ) {
...
}
else if ( hit instanceof Location ) {
...
}
else {
...
}
}
我正在用Hibernate Search 4.5.1和Spring 4.0.5版本构建一个应用程序。我正在尝试索引以下类: 我正在构建一个junit测试用例,看起来如下所示: 我还注意到在luke lucene上,一些索引词的长度最多为6个字符,例如,一首歌的艺术家是“后代”,而索引中存储的词是“the”和“offspr”。第一个可以,但第二个不应该是“后代”。为什么要截断名字?
问题内容: 我正在使用并希望elasticsearch返回搜索的单词而不仅仅是点击。当我搜索单词并且模糊搜索找到单词时,我想知道是谁找到了它。 数据: 查询: 该查询将返回,但不知道是否找到它。 有人知道该怎么做或一个主意吗?我希望输出为。 问题答案: 您可以为此命名查询,方法是为每个查询命名。在结果中,每个匹配都将包含一个数组,其中包含匹配的查询的名称(例如及以下)。
我们有一个需要跨多个索引查询的要求,如下所示 我们使用的是ElasticSearch 5.1.1. http://localhost:9200/index1,index2,index3/type1,type2/_search 查询: 但是,我们可能无法预先知道该索引是否存在,如果上述任何一个索引都不存在,我们将得到以下错误。 一个明显的方法是检查索引是否已经存在,但我希望避免额外的调用。 注意:至
我用java编写了一个实用的二叉搜索树,除了一个关键的函数,搜索。我使用的逻辑是,我将检查根是否为空,然后我要搜索的术语是否等于根(所以返回根)或>根(所以搜索右子树)或 使用printlns查看正在发生的事情,我发现如果值在那里,它将通过正确的if语句(包括将BNode n设置为找到的值),但随后由于某种原因将再次通过方法(返回null)。 这个方法唯一起作用的时候是在搜索根节点的时候,这对我来
我正在学习node,我正在尝试使用spotifyapi搜索并返回一个艺术家。页面加载了所有内容,但是当我尝试搜索时,我得到了这个错误 经过一番挖掘,我发现我出现这个错误的原因是: 在中,chunk正在返回 请求的路径(假定)是api.spotify.com/v1/search?q=sam
我有:一个实体有一个的集合,每个阶段都有一个的集合。Stage项可以有几种类型,我在JPA/Hibernate中使用它们作为带有鉴别器列的继承策略。 我需要lucene查询返回在类型a的阶段项(类中的字段)中具有特定细节的请求。我无法让hibernate搜索查看子类中的字段。 因此这个lucene查询不起作用(返回0个结果): 但基于中的字段进行搜索有效: