【发布时间】:2012-03-06 17:02:15
【问题描述】:
有没有一种简单的方法可以让 Hibernate Search 以小写形式索引其所有值?而不是默认的大小写混合。
我正在使用注释@Field。但我似乎无法配置一些应用程序级别的集合
【问题讨论】:
标签: hibernate-search
有没有一种简单的方法可以让 Hibernate Search 以小写形式索引其所有值?而不是默认的大小写混合。
我正在使用注释@Field。但我似乎无法配置一些应用程序级别的集合
【问题讨论】:
标签: hibernate-search
我是傻瓜! StandardAnalyzer 类已经 以小写形式进行索引。只需将搜索词设置为小写即可。我假设查询会这样做。
但是,如果要在应用程序范围内使用不同的分析器,则可以使用属性 hibernate.search.analyzer 进行设置。
【讨论】:
Analyzer 应用了小写、术语拆分、删除常用术语和许多更高级的语言处理功能。
通常,您应该使用用于索引的相同分析器来处理旨在匹配索引字符串的用户输入;配置 hibernate.search.analyzer 设置默认(全局)分析器,但您可以按索引、按实体类型、按字段甚至在不同的实体实例上自定义它。
例如,进行语言特定分析很有用,因此使用特定于中文的例程处理中文描述,使用意大利分词器处理意大利描述。
默认分析器适用于大多数用例,并且会在空格处小写和拆分术语。
还要考虑到,在使用 Lucene Queryparser 时,API 会要求您提供适当的分析器。
当使用 Hibernate Search QueryBuilder 时,它会尝试在每个字段上应用正确的分析器;另见http://docs.jboss.org/hibernate/search/4.1/reference/en-US/html_single/#search-query-querydsl。
【讨论】:
有多种方法可以仅在字符串类型字段中使排序不敏感。
1.第一种方法是在实体的字段/属性中添加@Fields注释。 喜欢
@Fields({@Field(index=Index.YES,analyze=Analyze.YES,store=Store.YES), @Field(index=Index.YES,name = "nameSort",analyzer = @Analyzer(impl=KeywordAnalyzer.class), store = Store.YES)})
私有字符串名称;
假设您有自定义分析器的名称属性并对其进行排序。所以这是不可能的,那么你可以在索引中添加新字段 nameSort 在该字段上应用排序。 您必须应用关键字分析器类,因为这不是 tokeniz 字段,并且默认情况下在字段中应用小写工厂类。
2.第二种方法是你可以在排序上实现你的比较类
@Override
public FieldComparator newComparator(String field, int numHits, int sortPos, boolean reversed) throws IOException {
return new StringValComparator(numHits, field);
}
用扩展FieldComparatorSource类创建一个类并实现上述方法。
使用 StringValComparator 创建新的类名并实现 FieldComparator 并实现以下方法
类 StringValComparator 扩展 FieldComparator {
private String[] values;
private String[] currentReaderValues;
private final String field;
private String bottom;
StringValComparator(int numHits, String field) {
values = new String[numHits];
this.field = field;
}
@Override
public int compare(int slot1, int slot2) {
final String val1 = values[slot1];
final String val2 = values[slot2];
if (val1 == null) {
if (val2 == null) {
return 0;
}
return -1;
} else if (val2 == null) {
return 1;
}
return val1.toLowerCase().compareTo(val2.toLowerCase());
}
@Override
public int compareBottom(int doc) {
final String val2 = currentReaderValues[doc];
if (bottom == null) {
if (val2 == null) {
return 0;
}
return -1;
} else if (val2 == null) {
return 1;
}
return bottom.toLowerCase().compareTo(val2.toLowerCase());
}
@Override
public void copy(int slot, int doc) {
values[slot] = currentReaderValues[doc];
}
@Override
public void setNextReader(IndexReader reader, int docBase) throws IOException {
currentReaderValues = FieldCache.DEFAULT.getStrings(reader, field);
}
@Override
public void setBottom(final int bottom) {
this.bottom = values[bottom];
}
@Override
public String value(int slot) {
return values[slot];
}
}
对喜欢的字段应用排序
new SortField("name",new StringCaseInsensitiveComparator(), true);
【讨论】: