使用NHibernate搜索的多态查询

时间:2012-02-07 12:53:54

标签: .net nhibernate lucene lucene.net nhibernate-search

我有多个实体存储在一个NHibernate Search索引中,希望我能够一次查询所有这些实体。用例是一个简单的搜索页面,返回混合结果。因此,例如,代码可能如下所示:

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实现类似多态查询的最简单方法是什么?

1 个答案:

答案 0 :(得分: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();
}