Полиморфные запросы с поиском 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?


person Thom    schedule 07.02.2012    source источник


Ответы (1)


Существует перегрузка 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();
}
person Thom    schedule 08.02.2012