开发者

Indexing subclass fields by IndexEmbedded

开发者 https://www.devze.com 2023-02-17 15:54 出处:网络
I\'m am using NHibernate.Search and Lucene.Net. I will ask if anyone have experienced similar problems. This is the situation regarding the followin开发者_JAVA百科g three classes.

I'm am using NHibernate.Search and Lucene.Net. I will ask if anyone have experienced similar problems. This is the situation regarding the followin开发者_JAVA百科g three classes.

[Indexed]
public class File 
{
    [Field]
    public virtual string FileId { get; private set; }

    [ContainedIn]
    public virtual List<Record> Records { get; private set; }
}

[Indexed]
public class CaseFile : File
{
    [Field]
    public virtual int CaseYear { get; set; }
    [Field]
    public virtual int CaseSequenceNumber { get; set; }
}

[Indexed]
public class Record
{
    [IndexedEmbedded]
    public virtual File ParentFile { get; set; }
}

The problem is when I try to index the record class. The goal is to get all fields of both the File class and the subclass CaseFile contained in the Record index. But when I index the Record class I only get fields of the File superclass in my Record index. The fields of the CaseFile subclass are missing in the Record index.

I have also tried the [IndexedEmbedded(TargetElement = typeof(CaseFile))] on the ParentFile property in the Record class, but this leads to totally empty indexes, or no indexing at all.

If I index the File class, the expected subclass properties are indexed as expected in the File index.

Have anyone experienced similar problems with Hibernate/NHibernate search?


I was having the same issue, and I managed to achieve a workaround by doing something similar to the following.

It's not the nicest solution though.

[Indexed]
public class File 
{
    [Field]
    public virtual string FileId { get; private set; }

    [ContainedIn]
    public virtual List<Record> Records { get; private set; }


    [Field(Index.Tokenized, Store = Store.Yes)]
    public virtual string CaseYearSearch
    {
        get
        {
            if(GetType() == typeof(CaseFile))
            {
                return ((CaseFile)this).CaseYear;
            }
            return "";
        }
    }

    [Field(Index.Tokenized, Store = Store.Yes)]
    public virtual string CaseSequenceNumberSearch
    {
        get
        {
            if(GetType() == typeof(CaseFile))
            {
                return ((CaseFile)this).CaseSequenceNumber;
            }
            return "";
        }
    }
}

public class CaseFile : File
{
    public virtual int CaseYear { get; set; }
    public virtual int CaseSequenceNumber { get; set; }
}

[Indexed]
public class Record
{
    [IndexedEmbedded]
    public virtual File ParentFile { get; set; }
}

I'm using a MultiFieldQueryParser to query.

IFullTextSession session = Search.CreateFullTextSession(Session);

var parser = new MultiFieldQueryParser(new[] { "File.CaseYearSearch", "File.CaseSequenceNumberSearch" }, new CustomAnalyzer());
parser.SetDefaultOperator(QueryParser.Operator.OR);

var booleanQuery = new BooleanQuery();
booleanQuery.Add(parser.Parse(terms), BooleanClause.Occur.MUST);
booleanQuery.Add(new TermQuery(new Term("Status", ((int)Status.Active).ToString())), BooleanClause.Occur.MUST);

return session.CreateFullTextQuery(booleanQuery, new[] { typeof(Record) });

Let me know if you find a cleaner solution.


I discussed the problem with Hibernate/NHibernate search and they confirmed that the situation is a bug.

They recommended using a custom class bridge to add the missing fields to the index I wanted it to be in.

This was much cleaner and I was satisified with this soluion until the source in Hibernate/NHibernate search is fixed.

0

精彩评论

暂无评论...
验证码 换一张
取 消