首页 > 其他分享 >获取一个索引文件频率最高的Term(可实现热点关键字的一个思路之一)

获取一个索引文件频率最高的Term(可实现热点关键字的一个思路之一)

时间:2023-09-07 10:32:41浏览次数:24  
标签:Term terms TermInfo 索引 fields term 关键字 频率


    前段时间同事也开始对搜索感兴趣,他看到luke工具界面上会显示Term的频率数,提出通过索引用户的搜索日志中的检索关键字,我们是否可以利用这个Field字段中Term频率高低来说明其是否代表热点关键字。

    想想觉得也是有一点在理,特别是对用户没有任何可分析性的情况下。但这就引出了一个问题:如何获取整个索引文件里频率最高的哪几个Term?

    翻了几次API,网上也搜了但没找到什么信息,仅仅看到网上有一篇文章讲到通过IndexReader取出所有的Term,然后再比较每一个的频率,最终得出最高频率的哪几个Term。但这又让我们顾虑的是当大数据量时如何确保其速度?

    既然luke可以在界面上展示出来,那它一定实现了这个功能,所以今天下了源代码,不过发现其已经不支持Lucene3.0.2,查看更新日志原来他们已经更新到可兼容未来Lucene4.0.0版本。最后从日志里找出已被删除的两个java文件:HighFreqTerms.java 和TermInfo.java,源代码如下(本人在里面添加了注释,如有错误请大家帮忙纠正,:-D):

import org.apache.lucene.index.Term; 
 
public 
 class TermInfo { 
 
   
 public Term term; 
 
   
 public 
 int docFreq; 
 //term频率 
 
   
 
   
 public TermInfo(Term t, 
 int df) { 
 
     
 this.term 
 = t; 
 
     
 this.docFreq 
 = df; 
 
  } 
 
} 
 
import org.apache.lucene.util.PriorityQueue; 
 
import org.apache.lucene.store.Directory; 
 
import org.apache.lucene.store.FSDirectory; 
 
import org.apache.lucene.index.IndexReader; 
 
import org.apache.lucene.index.TermEnum; 
 
import java.io.File; 
 
import java.util.Hashtable; 
 
/**
 * 获取一个索引文件中最高频率Term数组
 * <code>HighFreqTerms</code> class extracts terms and their frequencies out
 * of an existing Lucene index.
 *
 * @version $Id: HighFreqTerms.java,v 1.2 2003/11/08 10:55:40 Administrator Exp $
 */ 
 
public 
 class HighFreqTerms { 
 
     
 public 
 static 
 int defaultNumTerms 
 = 
 10; 
 //初始化默认取出top defaultNumTerms-1条 
 
     
 
     
 public 
 static 
 void main(String[] args) 
 throws Exception { 
 
        Directory dir 
 = FSDirectory.open( 
 new File( 
 "D://DATAMANAGER//INDEX//SYS_3000")); 
 
        TermInfo[] terms 
 = getHighFreqTerms(IndexReader.open(dir), null, 
 new String[]{ 
 "content"}); 
 
         
 for ( 
 int i 
 = 
 0; i 
 < terms.length; i 
 ++) { 
 
            System.out.println(i 
 + 
 "./t" 
 + terms[i].term 
 + 
 ":" 
 +terms[i].docFreq); 
 
        } 
 
    } 
 
     
 
     
 /**
     * 取出频率最高的term列表
     * @param ir IndexReader
     * @param junkWords Hashtable 过滤词
     * @param fields 可获取多个Field new String[]{"title","content"}
     * @return TermInfo[] 
     * @throws Exception
     */ 
 
     
 public 
 static TermInfo[] getHighFreqTerms(IndexReader ir, Hashtable junkWords, String[] fields) 
 throws Exception { 
 
         
 return getHighFreqTerms(ir, junkWords, defaultNumTerms, fields); 
 
    } 
 
     
 
     
 /**
     * 取出频率最高的term列表
     * @param reader IndexReader
     * @param junkWords Hashtable 过滤词
     * @param numTerms 初始化队列的大小即取出numTerms-1条
     * @param fields 可获取多个Field new String[]{"title","content"}
     * @return TermInfo[] 
     * @throws Exception
     */ 
 
     
 public 
 static TermInfo[] getHighFreqTerms(IndexReader reader, Hashtable junkWords, 
 int numTerms, String[] fields) 
 throws Exception { 
 
         
 if (reader 
 == null 
 || fields 
 == null) 
 return null; 
 
        TermInfoQueue tiq 
 = 
 new TermInfoQueue(numTerms); 
 //实例化一个numTerms大小存放TermInfo的队列 
 
        TermEnum terms 
 = reader.terms(); 
 //读取索引文件里所有的Term 
 
         
 int minFreq 
 = 
 0; 
 //队列最后一个Term的频率即当前最小频率值 
 
         
 while (terms.next()) { 
 //取出一个Term对象出来 
 
            String field 
 = terms.term().field(); 
 
             
 if (fields 
 != null 
 && fields.length 
 > 
 0) { 
 
                 
 boolean skip 
 = true; 
 //跳过标识 
 
                 
 for ( 
 int i 
 = 
 0; i 
 < fields.length; i 
 ++) { 
 
                     
 if (field.equals(fields[i])) { 
 //当前Field属于fields数组中的某一个则不跳过 
 
                        skip 
 = false; 
 
                         
 break; 
 
                    } 
 
                } 
 
                 
 if (skip) 
 continue; 
 
            } 
 
             
 //当前term的内容是过滤词,则直接跳过 
 
             
 if (junkWords 
 != null 
 && junkWords.get(terms.term().text()) 
 != null) 
 continue; 
 
            
 
             
 //获取最高频率term的核心代码 
 
             
 //(队列底层是最大频率Term,顶层是最小频率Term,当插入一个元素后超出初始化队列大小则pop最上面的那个元素,重新设置最小频率值minFreq) 
 
             
 if (terms.docFreq() 
 > minFreq) { 
 //当前Term的频率大于最小频率则插入队列中 
 
                tiq.insertWithOverflow( 
 new TermInfo(terms.term(), terms.docFreq())); 
 
                 
 if (tiq.size() 
 > 
 = numTerms) 
 // if tiq overfull 当队列中的个数大于numTerms 
 
                { 
 
                    tiq.pop();   
 // remove lowest in tiq 取出最小频率的元素即最上面的一个元素 
 
                    minFreq 
 = ((TermInfo)tiq.top()).docFreq; 
 // reset minFreq 重新设置当前最顶层Term的频率为minFreq 
 
                } 
 
            } 
 
        } 
 
         
 //pop出队列元素,最终存放在数组中元素的term频率按从大到小排列 
 
        TermInfo[] res 
 = 
 new TermInfo[tiq.size()]; 
 
         
 for ( 
 int i 
 = 
 0; i 
 < res.length; i 
 ++) { 
 
            res[res.length 
 - i 
 - 
 1] 
 = (TermInfo)tiq.pop(); 
 
        } 
 
         
 return res; 
 
    } 
 
} 
 
//队列,用于term频率比较的队列 
 
final 
 class TermInfoQueue 
 extends PriorityQueue 
 <TermInfo 
 > { 
 
    TermInfoQueue( 
 int size) { 
 
        initialize(size); 
 
    } 
 
     
 protected 
 final 
 boolean lessThan(TermInfo a, TermInfo b) { 
 
         
 return a.docFreq 
 < b.docFreq; 
 
    } 
 
}

标签:Term,terms,TermInfo,索引,fields,term,关键字,频率
From: https://blog.51cto.com/u_2544485/7394859

相关文章

  • 阿里巴巴API接口解析,实现按关键字搜索商品
    要解析阿里巴巴API接口并实现按关键字搜索商品,你需要进行以下步骤:了解阿里巴巴API接口文档:访问阿里巴巴开放平台,找到API文档,了解阿里巴巴提供的API接口以及相关的参数、返回值等信息。注册开发者账号:在阿里巴巴开放平台上注册一个开发者账号,并创建一个应用,获取到API权限。获取API密......
  • Kuberners 强制删除pod 强制删除Terminating的NAMESPACE 强制删除ns
    强制删除NAMESPACE[root@k8s-master1~]#catdelete.sh#!/bin/bashset-eopipefaildie(){echo"$*"1>&2;exit1;}need(){which"$1"&>/dev/null||die"Binary'$1'ismissingbutrequired"......
  • 软件测试|MySQL DISTINCT关键字过滤重复数据
    简介在MySQL中,有时候我们需要从表中检索唯一的、不重复的数据。这时,我们可以使用DISTINCT关键字来过滤掉重复的数据行。在本文中,我们将深入探讨MySQL中DISTINCT的用法以及如何在查询中使用它来得到不重复的结果集。基本语法DISTINCT关键字用于在SELECT语句中指示查询结果中去除重复......
  • python3中所有保留字(关键字)
     Python3中的保留字(关键字)|AmosCloudWiki   ......
  • [转]Mysql中普通索引key 、主键索引(primary key) 、唯一索引(unique key)与index区别
    原文地址:Mysql中普通索引key、主键索引(primarykey)、唯一索引(uniquekey)与index区别-元小疯-博客园一、索引的定义和由来:    索引被用来快速找出在一个列上用一特定值的行。没有索引,MySQL不得不首先以第一条记录开始并然后读完整个表直到它找出相关的行。 ......
  • mysql索引
    1先建表,插入数据,建索引,脚本如下:--建表createtableUser(idbigintauto_incrementprimarykey,namenvarchar(100),ageint,positionnvarchar(100));--插入数据INSERTI......
  • explain | 索引优化
    前言对于互联网公司来说,随着用户量和数据量的不断增加,慢查询是无法避免的问题。一般情况下如果出现慢查询,意味着接口响应慢、接口超时等问题。如果是高并发的场景,可能会出现数据库连接被占满的情况,直接导致服务不可用。慢查询的确会导致很多问题,我们要如何优化慢查询呢?主要解决......
  • 重建索引
    alert日志报错信息:[oracle@hd04trace]$catalert_db12c.log|grep"corrupt"-A2-B2|moreHexdumpof(file11,block704337)intracefile/app/oracle/diag/rdbms/orcl/db12c/trace/db12c_p006_20208.trcReadingdatafile'/app/oracle/oradata/orcl/d......
  • mongo 数据库建索引不规范导致奔溃
    2023年9月5日,在给3亿条数据库新建索引时,因为没有采用后台索引的方式导致数据库奔溃20分钟。前台建索引容易阻塞主线程,大的表一定要做background执行,否则堵塞全部读写建议后期操作:db.test.createIndex({name:1},{background:true}) ......
  • terminal 显示带颜色的字符
    参考https://blog.csdn.net/u014470361/article/details/81512330终端显示字体背景和字体颜色等使用用法可输入以下指令查看其使用方法manconsole_codes在命令行下能产生五颜六色的字体和图案,只需要加上一些颜色代码,例如:printf(“\033[0;30;41mcolor!!!\033[0m......