2012-02-07 92 views
2

我有多個實體存儲在一個單一的NHibernate搜索索引,希望我能夠一次查詢所有這些。用例是一個簡單的搜索頁面,它返回混合結果。因此,舉例來說,代碼看起來是這樣的:NHibernate搜索多態查詢

public interface ISearchable {} 

[Indexed(Index = "TheIndex")] 
public class SearchableEntityA : ISearchable 
{ 
    // Some [Field]s 
} 

[Indexed(Index = "TheIndex")] 
public class SearchableEntityB : ISearchable 
{ 
    // Some other [Field]s 
} 

這一切指標正常,當然是可查詢的原始NHibernate的,像這樣:

session.CreateCriteria<ISearchable>().List<ISearchable>(); 

我有ISearchable某些領域,但這些在NHibernate映射中沒有特別引用。

希望是,我可以只說:

var query = "some keyword"; 
fullTextSession.CreateFullTextQuery<ISearchable>(query).List<ISearchable>(); 

和檢索ISearchables的列表,包含來自各種不同的實體結果。然而,現實是它拋出了NHibernate.HibernateException: Not a mapped entity: NetComposites.Model.ISearchable

那麼,用NHibernate Search實現類似多態查詢的最簡單方法是什麼?

回答

2

CreateFullTextQuery過載存在允許您指定類型的搜索:

fullTextSession.CreateFullTextQuery(query, typeof(EntityA), typeof(EntityB)).List<ISearchable>(); 

這是指定所有類型有點麻煩,但它們的加載罰款。我唯一剩下的問題是,我認爲您可以默認進行所有字段搜索的假設是錯誤的,因此它需要在所有可搜索實體的所有屬性上構建一個MultiFieldQueryParser

private static Query ParseQuery(string query, IFullTextSession searchSession) 
{ 
    var parser = new MultiFieldQueryParser(GetAllFieldNames(searchSession), new StandardAnalyzer()); 
    return parser.Parse(query); 
} 

private static string[] GetAllFieldNames(IFullTextSession searchSession) 
{ 
    var reader = 
     searchSession.SearchFactory.ReaderProvider.OpenReader(
      searchSession.SearchFactory.GetDirectoryProviders(typeof (Company))); 
    var fieldNames = reader.GetFieldNames(IndexReader.FieldOption.ALL); 
    return fieldNames.Cast<string>().ToArray(); 
}