2012-02-07 102 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(); 
}