Lucene读书笔记——5. 高级搜索技术

Lucene域缓存

为所有文档加载域值
float[] weigths = FieldCache.DEFAULT.getFloats(reader, "weight");
weights[docid] = the value of weight field.

域缓存只能包含单个项的域。这通常意味着该域在被索引时需要使用参数Index.NOT_ANALYZED 或 Index.NOT_ANALYZED_NO_NORMS,如果使用KeywordAnalyzer等分析器的话,这些域还是可以被分析的,该分析过程只产生一个语汇单元。

只有关闭reader并去掉引用后才会清楚缓存中的数据记录(以reader为主键的WeakHashMap时在后台使用的)

段对应的reader
Lucene核心功能传入域缓存的reader参数将永远为一个reader对应一个段 。当重新打开一个IndexReader时,这个处理方式能带来很大好处;只有新生成的段才必须加载至域缓存。

对搜索结果进行排序

根据域值进行排序
在默认情况下,接受Sort对象参数的search方法不会对匹配文档进行任何评分操作。因为评分操作会消耗大量的系统性能,并且很多程序在通过域排序时并不需要进行评分操作。如果你的应用程序并不需要评分操作,那么最好时使用默认搜索方法。当需要使用其他搜索方法时,可以使用IndexSearcher类的setDefaultFieldSortScoring( )方法,该方法有2个布尔类型参数:doTrackScores 和 doMaxScore

doTrackScores置为true,那么 每个搜索命中结果都会被进行评分操作。
doMaxScore为true,那么程序将对 最大分值的搜索命中结果进行评分操作。

Searcher searcher = new IndexSearcher(directory);

searcher.setDefaultFieldSortScoring(true, false);
TopDocs results = searcher.search(query, null, 20, sort); // sort传进来

new Sort(new SortField("category", SortField.INT, true))

Sort.RELEVANCE       与 new Sort()等效
Sort.INDEXORDER   


按照相关性进行排序
Sort.RELEVANCE       与 new Sort()等效

按照索引顺序进行排序
Sort.INDEXORDER  

通过域进行排序
new Sort(new SortField("category",  SortField.String, true)); //最后一个参数用来是否是reverse

倒排序
new Sort(new SortField("category",  SortField.String, true)); //最后一个参数用来是否是reverse

通过多个域进行排序
new Sort(new SortField("category", SortField.STRING), SortField.FIELD_SCORE, new SortField("pubmonth", SortField.INT, true));


为排序域选择类型
使用非默认的locale方式进行排序
public SortField(String field, Locale locale, boolean reverse); 

使用MultiPhraseQuery

该类是一次指定多个Term对一个field进行查询

MultiPhraseQuery query = new MultiPhraseQuery();
query . add( new Term[]{ new Term( "field" , "quick" ), new Term( "field" , "fast" )} );//一次指定2个
query .add( new Term( "field" , "fox" ));//再指定一个

针对多个域的一次性查询
Query query = new MultiFieldQueryParser(Version. LUCENE_30 , new String[]{ "title" , "subject" }, new SimpleAnalyzer()).parse( "development" );

跨度查询

跨度查询是指域中的起始语汇单元和终止语汇单元的位置。 如使用   靠近“president obama”且包含“health care reform”这样的搜索条件


与TermQuery做个比较,TermQuery只是对文档进行简单的匹配操作,而SpanTermQuery除了完成这个功能, 还会保留每个匹配文档对应的项位置信息。
总的来说,跨度查询是一种计算密集型操作。

TermQuery找到包含对应的文档时,它会记录该匹配文档并且进行下一个文档的查询操作;而SpanTermQuery却必修列举出该项在该文档中所有的出现地点。


SpanQuery类型 描   述
SpanTermQuery 和其他跨度查询类型结合使用。单独使用时相当于TermQuery
SpanFirstQuery 用来匹配各个域的首部分的各个跨度
SpanNearQuery 用来匹配临近跨度
SpanNotQuery 用来匹配不重叠的跨度
FieldMaskingSpanQuery 封装其他SpanQuery类,但程序会认为已匹配到另外的域。该功能可用于针对多个域的跨度查询
SpanOrQuery 跨度查询的聚合匹配


跨度查询的构建模块:SpanTermQuery

           SpanTermQuery query = new SpanTermQuery( new Term( "field" , "the" ));
           IndexSearcher searcher = new IndexSearcher( new RAMDirectory());
           IndexReader reader = searcher .getIndexReader();
           Spans spans = query .getSpans( reader );
           Analyzer analyzer = new WhitespaceAnalyzer();
            while ( spans .next()) {
                 int id = spans .doc();
                Document doc = reader .document( id );
                TokenStream stream = analyzer .tokenStream( "contents" , new StringReader( doc .get( "f" )));
                TermAttribute term = stream .addAttribute(TermAttribute. class );
                 int i = 0;
                 while ( stream .incrementToken()) {
                      if ( i == spans .start()) {
                           
                     }
                      term .term();
                      if ( i +1 == spans .end()) {
                           
                     }
                }
           }

在域的起点查找跨度
SpanFirstQuery sfq = new SpanFirstQuery(brown, 2); //从开始找2个跨度,找brown

彼此相邻的跨度
SpanQuery[] quick_brown_dog = new SpanQuery[]{quick, brown, dog};

SpanNearQuery snq = new SpanNearQuery( quick_brown_dog, 4, true); //每个之间距离最大为4,第三个参数true为正顺序


在匹配结果中排除重叠的跨度

SpanNearQuery quick_fox = new SpanNearQuery(new SpanQuery[]{quick, fox}, 1, true);

SpanNotQuery quick_fox_dog = new SpanNotQuery(quick_fox, dog); //第一个参数表示要包含的, 第二个表示要排除的

SpanOrQuery类

SpanOrQuery or = new SpanOrQuery(new SpanQuery[]{first, second}); //

SpanQuery类和QueryParser类
捐赠模块里的QueryParser类可以支持SpanQuery

搜索过滤

TermRangeFilter 只对包含特定范围的文档进行操作。功能与TermRangeQuery类似
NumericRangeFilter 只对特定域的特定值范围进行文档匹配操作。功能与NumericRangeQuery一致,但前者没有评分操作
FieldCacheTermsFilter 针对特定项进行文档匹配操作,使用时可以结合FieldCache获得更好的性能表现
FieldCacheRangeFilter 针对某个项或者某个数值范围进行文档操作,使用时可以结合FieldCache获得更好的性能
QueryWrapperFilter
SpanQueryFilter
PrefixFilter  只匹配包含特定域和特定前缀的项的文档。
CachingWrapperFilter是其他过滤器的封装器,它将结果缓存起来以便再次使用,从而提高系统性能。
CachingSpanFilter 与上者一致,但是缓冲的目标是SpanFilter
FilterDocIdSet 允许对过滤器进行过滤,一次处理一个文档,首先派生它的子类,然后在该子类中定义匹配方法。

TermRangeFilter
NumericRangeFilter
FieldCacheRangeFilter
特定项过滤
使用QueryWarpperFilter类
使用SpanQueryFilter类
安全过滤器
使用BooleanQuery类进行过滤
PrefixFilter
缓存过滤结果
将filter封装成query
对过滤器进行过滤
非Lucene内置的过滤器

使用功能查询实现自定义评分
功能查询的相关类
使用功能查询对最近修改过的文档进行加权

针对多索引的搜索
使用MultiSearch类
MultiSearcher searcher = new MultiSearcher(searchers);

使用ParallelMultiSearch进行多线程搜索

使用项向量
查找相似书籍
它属于哪个类别
TermVectorMapper类

使用FieldSelector加载域

停止较慢的搜索
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值