zoukankan      html  css  js  c++  java
  • Lucene.Net实现GroupBy的效果(2.3.1版)

    本文简单介绍Lucene.Net实现GroupBy效果的方法,与《Lucene.Net 按类别统计搜索结果数 》一文类似。注意,这种使用方法很影响效率,特别是命中结果多的情况下。这段代码修正自2.3.1版本,其它版本可能会与此有差别。

    改造方法仍然是修改IndexSearcher,这里不再修改类库,而是通过自己的代码来实现。

    扩充IndexSearcher类
    实现与 HitQueue类完全一致,只因为这里无法使用类库提供的构造函数
        /// <summary>
        
    /// 增加新的TopDocCollector类,无法直接继承TopDocCollector
        
    /// </summary>
        public class TopDocCollectorExtension : HitCollector
        {
            
    private ScoreDoc reusableSD;

            
    internal int totalHits;
            
    internal PriorityQueue hq;

            
    /// <summary>Construct to collect a given number of hits.</summary>
            
    /// <param name="numHits">the maximum number of hits to collect
            
    /// </param>
            public TopDocCollectorExtension(int numHits)
                : 
    this(numHits, new HitQueueExtension(numHits))
            {
            }
            
    /// <summary>
            
    /// 注入IndexSearcherExtension对象
            
    /// </summary>
            private IndexSearcherExtension searcher;
            
    /// <summary>
            
    /// 构造函数注入对象
            
    /// </summary>
            
    /// <param name="numHits"></param>
            
    /// <param name="searcher"></param>
            public TopDocCollectorExtension(int numHits, IndexSearcherExtension searcher)
                : 
    this(numHits)
            {
                
    this.searcher = searcher;
            }

            
    internal TopDocCollectorExtension(int numHits, PriorityQueue hq)
            {
                
    this.hq = hq;
            }

            
    /// <summary>
            
    /// 临时数据,用于排重
            
    /// </summary>
            private Dictionary<intint> dict = new Dictionary<intint>();
            
    // javadoc inherited
            public override void Collect(int doc, float score)
            {
                
    if (score > 0.0f)
                {
                    
    //排重算法
                    if (!string.IsNullOrEmpty(searcher.FieldName))
                    {
                        IndexReader reader 
    = searcher.GetIndexReader();
                        Document docment 
    = reader.Document(doc);
                        
    string value = docment.Get(searcher.FieldName).Trim();
                        
    string value1 = string.Empty;
                        
    string value2 = string.Empty;
                        
    int len = value.Length;
                        
    int len1 = (int)Math.Ceiling(len / 2.0f);
                        
    int len2 = len - len1;
                        
    int hash1 = value.Substring(0, len1).GetHashCode();
                        
    int hash2 = value.Substring(len1, len2).GetHashCode();
                        
    if (!(dict.ContainsKey(hash1) && dict.ContainsValue(hash2)))
                            dict.Add(hash1, hash2);
                        
    else
                            
    return;
                    }

                    totalHits
    ++;
                    
    if (reusableSD == null)
                    {
                        reusableSD 
    = new ScoreDoc(doc, score);
                    }
                    
    else if (score >= reusableSD.score)
                    {
                        
    // reusableSD holds the last "rejected" entry, so, if
                        
    // this new score is not better than that, there's no
                        
    // need to try inserting it
                        reusableSD.doc = doc;
                        reusableSD.score 
    = score;
                    }
                    
    else
                    {
                        
    return;
                    }
                    reusableSD 
    = (ScoreDoc)hq.InsertWithOverflow(reusableSD);
                }
            }

            
    /// <summary>The total number of documents that matched this query. </summary>
            public virtual int GetTotalHits()
            {
                
    return totalHits;
            }

            
    /// <summary>The top-scoring hits. </summary>
            public virtual TopDocs TopDocs()
            {
                ScoreDoc[] scoreDocs 
    = new ScoreDoc[hq.Size()];
                
    for (int i = hq.Size() - 1; i >= 0; i--)
                    
    // put docs in array
                    scoreDocs[i] = (ScoreDoc)hq.Pop();

                
    float maxScore = (totalHits == 0? System.Single.NegativeInfinity : scoreDocs[0].score;

                
    return new TopDocs(totalHits, scoreDocs, maxScore);
            }
        }
    OK生产者完成了,下面看看消费者怎么搞。
            static void Main(string[] args)
            {
                IndexWriter writer 
    = new IndexWriter("e:\\index"new StandardAnalyzer(), true);
                Document doc 
    = new Document();
                doc.Add(
    new Field("field""query value!", Field.Store.YES, Field.Index.TOKENIZED));
                writer.AddDocument(doc);
                writer.AddDocument(doc);
                writer.AddDocument(doc);
                writer.Close();

                IndexSearcherExtension searcher 
    = new IndexSearcherExtension("e:\\index");
                searcher.GroupBy(
    "field");
                Query q 
    = new QueryParser("field"new StandardAnalyzer())
                    .Parse(
    "query");
                Hits docs 
    = searcher.Search(q);
                
    for (int i = 0; i < docs.Length(); i++)
                {
                    Console.WriteLine(docs.Doc(i).Get(
    "field"));
                }
                searcher.Close();

                Console.ReadKey();
            }
    添加了三个相同的文档,结果只查询到一个结果,从而达到了目的。这段修改比较简单,应该还可以设计出更加高效的算法。好长时间没写博客有些生疏了~~!
  • 相关阅读:
    SQLPrompt 7.2发布
    安装SQL Server2016正式版
    Coping with the TCP TIME-WAIT state on busy Linux servers
    分区里的inode号是0号和1号的block
    如何知道SQL Server机器上有多少个NUMA节点
    使用开源软件的原因
    一起来测试天兔Lepus3.8 Beta版本的MSSQL部分
    新书到手 TRANSACTION PROCESSING:CONCEPTS AND TECHNIQUES
    在线即时展现 Html、JS、CSS 编辑工具
    在触屏设备上面利用html5裁剪图片
  • 原文地址:https://www.cnblogs.com/birdshover/p/1533368.html
Copyright © 2011-2022 走看看