我們需要從一個資料屬性中索引不同的欄位。這個問題已經通過實作FieldBridge來解決了,并在那里添加欄位。 正如在hibernate搜索參考資料中的這個例子中所看到的:
/**.
* 將日期存盤在3個不同的欄位中--年、月、日--以方便按RangeQuery的創建。
* 年、月或日(例如,獲得過去5年中12月的所有元素)。
* @author Emmanuel Bernard
*/
public class DateSplitBridge implements FieldBridge {
private final static TimeZone GMT = TimeZone. getTimeZone("GMT")。
public void set(String name, Object value, Document document,
LuceneOptions luceneOptions) {
Date date =(Date)值。
Calendar cal = GregorianCalendar.getInstance(GMT)。
cal.setTime(date)。
int year = cal.get(Calendar.YEAR)。
int month = cal.get(Calendar.MONTH) 1;
int day = cal.get(Calendar.Day_OF_MONTH)。
//設定年份。
luceneOptions.addFieldToDocument(
name ".year"。
String.valueOf( year ),
檔案)。)
//設定月份并在需要時填充它。
luceneOptions.addFieldToDocument(
name ".month",
month < 10 ? "0" : "" String.valueOf( month ) 。
document )。
//設定日期并在需要時填充它。
luceneOptions.addFieldToDocument(
name ".day",
day < 10 ? "0" : "" String.valueOf( day ) 。
document )。
}
}
//property@FieldBridge(impl = DateSplitBridge.class)
private Date date日期。
除了上面的例子之外,我們還把我們的設定成了一個twoWayFieldBridge:
public class DateSplitBridge implements TwoWayFieldBridge {
[...]
public Object get(String name, Document document) {
final IndexableField field = document.getField(name)。
if (field != null) {
return field.stringValue()。
} else {
return null;
}
}
; }
public String objectToString(Object object) {
return object.toString()。
}
問題是,當搜索通過FieldBridge定義的欄位之一時,搜索似乎不知道它:
原因是:org.hibernate.search.exception.SearchException。無法 在[...]中找到date.day欄位。 org.hibernate.search.engine.spi.DocumentBuilderIndexedEntity.objectToString(DocumentBuilderIndexedEntity.java:1052)
如果欄位被映射(根據注釋或API),則不會出現錯誤:
如果欄位被映射(根據注釋或API),則不會出現錯誤:
//property
private Date日期。
但是在索引時出現了一個錯誤,因為Field在映射和FieldBridge中被定義了,這導致了:
2021-09-08 08:42:50,063 ERROR org.hibernate.search.exception.impl.LogErrorHandler:71 - hsearch000058: hsearch000183: 無法索引[...]型別的實體。 java.lang.IllegalArgumentException。DocValuesField "date.day" 在本檔案中出現了不止一次(只允許一個值)。 中出現了多次(每個欄位只允許有一個值),在 org.apache.lucene.index.SortedDocValuesWriter.addValue(SortedDocValuesWriter.java:62) ...
這應該如何處理?我們如何將欄位從FieldBridge傳播到搜索中,以使它們在第一時間被搜索到?
uj5u.com熱心網友回復:
問題出在你的查詢上,而不是在橋上。第一個橋段定義的欄位并不叫day,而是叫<不管你的屬性名稱是什么>.day。在你的例子中,這將是date.day。
請看這部分代碼:
luceneOptions.addFieldToDocument(
name ".day", //here.
day < 10 ? "0" : "" String.valueOf( day ) 。
檔案)。)
只要改變你的查詢,使用date.day而不是day。
無恥之徒:如果你可以的話,你真的應該考慮升級到Hibernate Search 6,在那里橋支持要強大得多,有更完善的檔案
。uj5u.com熱心網友回復:
Hibernate Search無法將你傳遞給Search DSL的值轉化為Lucene查詢中使用的值,因為欄位date.day沒有在Hibernate Search元資料中被參考,所以它不知道其預期型別。
讓你的橋實作MetadataProvidingFieldBridge,以便 Hibernate Search 知道該欄位。
如果這不起作用,您可以在使用搜索 DSL 構建查詢時始終使用 .ignoreFieldBridge().ignoreAnalyzer() 。例如:
queryBuilder.keyword()
.onField( "date.day"/span> )
.ignoreFieldBridge().ignoreAnalyzer()
.匹配( "10" )
.創建查詢()
提醒其他沒有看到其他答案的用戶:如果可以的話,你真的應該考慮升級到Hibernate Search 6,在那里橋支持要強大得多,有更完善的檔案
。轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/309845.html
標籤:
上一篇:JPA洗掉不執行
