如何使用Lucene.Net索引和搜索业务实体?

时间:2021-06-17 03:09:29

I would like to know how to use Lucene.NET for indexing and searching my business entities. I see NHibernate.Search has nice features for this issue, but it still needs DB. I don't need DB, I only want to store all data in my Lucene.NET's index. I also see java framework like Compass can do that stuff easily, but it's not .NET library.

我想知道如何使用Lucene.NET来索引和搜索我的业务实体。我看到NHibernate.Search对这个问题有很好的功能,但它仍然需要DB。我不需要DB,我只想将所有数据存储在我的Lucene.NET索引中。我也看到像Compass这样的Java框架可以很容易地做到这一点,但它不是.NET库。

Is there any ways for object designs or frameworks to solve this issue?

对象设计或框架有什么方法可以解决这个问题吗?

1 个解决方案

#1


try this code to use Lucene.NET to index a snapshot of business entities.., this has obvious limitations on type of properties and needs error checking but gives you a general idea of how to achieve this..

尝试使用Lucene.NET来索引业务实体的快照...,这对属性类型有明显的限制,需要进行错误检查,但是会让你大致了解如何实现这一点。

public class IndexHelper
{
    static Analyzer analyzer = new StandardAnalyzer();
    // Store the index in memory:
    static Directory directory = new RAMDirectory();
    static IndexWriter iwriter;

    static Dictionary<string, List<WeakReference>> indexedObjects = new Dictionary<string, List<WeakReference>>();

    static IndexHelper()
    {
        iwriter = new IndexWriter(directory, analyzer, true);
        iwriter.SetMaxFieldLength(25000);
    }

    public static void IndexObject(object entity)
    {
        Document doc = new Document();
        PropertyInfo[] entityProperties = entity.GetType().GetProperties();
        string entityKey = entity.GetHashCode().ToString();

        List<WeakReference> entityList;

        if (indexedObjects.TryGetValue(entityKey, out entityList) == false)
        {
            entityList = new List<WeakReference>();
            indexedObjects.Add(entityKey, entityList);
        }

        entityList.Add(new WeakReference(entity));

        doc.Add(new Field("@HASH", entityKey, Field.Store.YES, Field.Index.UN_TOKENIZED));

        foreach (PropertyInfo pInfo in entityProperties)
        {
            String propertyName = pInfo.Name;
            object propertyValue = pInfo.GetValue(entity, null); //Assuming all properties are of non index type
            String text = "null";
            if (propertyValue != null) text = propertyValue.ToString();

            doc.Add(new Field(propertyName, text, Field.Store.YES,
                Field.Index.TOKENIZED));
        }

        iwriter.AddDocument(doc);
        iwriter.Close();

    }

    public static List<WeakReference> Search(string queryString, string fieldName)
    {
        // Now search the index:
        IndexSearcher isearcher = new IndexSearcher(directory);

        Lucene.Net.QueryParsers.QueryParser qp = new Lucene.Net.QueryParsers.QueryParser(fieldName, analyzer);
        qp.SetDefaultOperator(Lucene.Net.QueryParsers.QueryParser.OR_OPERATOR);
        qp.SetLowercaseExpandedTerms(true);


        Query query = qp.Parse(queryString);

        List<WeakReference> results = new List<WeakReference>();
        Hits hits = isearcher.Search(query);
        // Iterate through the results:
        for (int i = 0; i < hits.Length(); i++)
        {
            Document hitDoc = hits.Doc(i);

            List<WeakReference> matchedObjects;

            if (indexedObjects.TryGetValue(hitDoc.GetField("@HASH").StringValue(), out matchedObjects))
            {
                results.AddRange(matchedObjects);
            }

        }

        isearcher.Close();

        return results;
    }
}

Update: Also look into this project http://www.codeplex.com/linqtolucene

更新:另请参阅此项目http://www.codeplex.com/linqtolucene

#1


try this code to use Lucene.NET to index a snapshot of business entities.., this has obvious limitations on type of properties and needs error checking but gives you a general idea of how to achieve this..

尝试使用Lucene.NET来索引业务实体的快照...,这对属性类型有明显的限制,需要进行错误检查,但是会让你大致了解如何实现这一点。

public class IndexHelper
{
    static Analyzer analyzer = new StandardAnalyzer();
    // Store the index in memory:
    static Directory directory = new RAMDirectory();
    static IndexWriter iwriter;

    static Dictionary<string, List<WeakReference>> indexedObjects = new Dictionary<string, List<WeakReference>>();

    static IndexHelper()
    {
        iwriter = new IndexWriter(directory, analyzer, true);
        iwriter.SetMaxFieldLength(25000);
    }

    public static void IndexObject(object entity)
    {
        Document doc = new Document();
        PropertyInfo[] entityProperties = entity.GetType().GetProperties();
        string entityKey = entity.GetHashCode().ToString();

        List<WeakReference> entityList;

        if (indexedObjects.TryGetValue(entityKey, out entityList) == false)
        {
            entityList = new List<WeakReference>();
            indexedObjects.Add(entityKey, entityList);
        }

        entityList.Add(new WeakReference(entity));

        doc.Add(new Field("@HASH", entityKey, Field.Store.YES, Field.Index.UN_TOKENIZED));

        foreach (PropertyInfo pInfo in entityProperties)
        {
            String propertyName = pInfo.Name;
            object propertyValue = pInfo.GetValue(entity, null); //Assuming all properties are of non index type
            String text = "null";
            if (propertyValue != null) text = propertyValue.ToString();

            doc.Add(new Field(propertyName, text, Field.Store.YES,
                Field.Index.TOKENIZED));
        }

        iwriter.AddDocument(doc);
        iwriter.Close();

    }

    public static List<WeakReference> Search(string queryString, string fieldName)
    {
        // Now search the index:
        IndexSearcher isearcher = new IndexSearcher(directory);

        Lucene.Net.QueryParsers.QueryParser qp = new Lucene.Net.QueryParsers.QueryParser(fieldName, analyzer);
        qp.SetDefaultOperator(Lucene.Net.QueryParsers.QueryParser.OR_OPERATOR);
        qp.SetLowercaseExpandedTerms(true);


        Query query = qp.Parse(queryString);

        List<WeakReference> results = new List<WeakReference>();
        Hits hits = isearcher.Search(query);
        // Iterate through the results:
        for (int i = 0; i < hits.Length(); i++)
        {
            Document hitDoc = hits.Doc(i);

            List<WeakReference> matchedObjects;

            if (indexedObjects.TryGetValue(hitDoc.GetField("@HASH").StringValue(), out matchedObjects))
            {
                results.AddRange(matchedObjects);
            }

        }

        isearcher.Close();

        return results;
    }
}

Update: Also look into this project http://www.codeplex.com/linqtolucene

更新:另请参阅此项目http://www.codeplex.com/linqtolucene