Lucene的排序是通过FieldComparator及其子类实现的,以StringOrdValComparator作为例子详细说明lucene的排序的基于缓存FieldCache实现。
思路:用一个数组保存某个filed字段对应的所有的document的最大的一个term。这个数组的index就是docId,值对应所有这个filed所有term的数组的index
StringOrdValComparator 类里面的
private String[] lookup; 值为某个filed的所有的term的值
private int[] order; index为docId,值为lookup的index,表示某个document的某个field的最大的term的在lookup中的index。
排序的时候根据docId查询出order[docId]值的大小比较。
初始化
IndexSearcher# public void search(Weight weight, Filter filter, Collector collector) 方法中调用的TopFieldCollector#OneComparatorNonScoringCollector.setNextReader
调用FieldComparator#StringOrdValComparator. setNextReadercollector.setNextReader(subReaders[i], docStarts[i]);
方法中调用
FieldCache.DEFAULT.getStringIndex(reader, field)
初始化filed对应的所有的term信息和frg信息。String就从””开始读取直到读完,
算法是在FieldCacheImpl#StringIndexCache.createValue实现的
代码如下结果就是某个document的对应的某个term的最大值
@Override
protected Object createValue(IndexReader reader, Entry entryKey)
throws IOException {
String field = StringHelper.intern(entryKey.field);
final int[] retArray = new int[reader.maxDoc()];
String[] mterms = new String[reader.maxDoc()+1];
TermDocs termDocs = reader.termDocs();
TermEnum termEnum = reader.terms (new Term (field));
int t = 0; // current term number
// an entry for documents that have no terms in this field
// should a document with no terms be at top or bottom?
// this puts them at the top - if it is changed, FieldDocSortedHitQueue
// needs to change as well.
mterms[t++] = null;
try {
do {
Term term = termEnum.term();
if (term==null || term.field() != field) break;
// store term text
// we expect that there is at most one term per document
if (t >= mterms.length) throw new RuntimeException ("there are more terms than " +
"documents in field \"" + field + "\", but it's impossible to sort on " +
"tokenized fields");
mterms[t] = term.text();
termDocs.seek (termEnum);
while (termDocs.next()) {
retArray[termDocs.doc()] = t;
}
t++;
} while (termEnum.next());
} finally {
termDocs.close();
termEnum.close();
}
if (t == 0) {
// if there are no terms, make the term array
// have a single null entry
mterms = new String[1];
} else if (t < mterms.length) {
// if there are less terms than documents,
// trim off the dead array space
String[] terms = new String[t];
System.arraycopy (mterms, 0, terms, 0, t);
mterms = terms;
}
StringIndex value = new StringIndex (retArray, mterms);
return value;
}
};
排序的实现
Lucene的查询结果是放在优先队列里面的,优先对象是通过org.apache.lucene.search.FieldComparator.StringOrdValComparator进行比较的。比较的StringOrdValComparator. Compare方法
@Override
public int compare(int slot1, int slot2) {
if (readerGen[slot1] == readerGen[slot2]) {
int cmp = ords[slot1] - ords[slot2];
if (cmp != 0) {
return cmp;
}
}
final String val1 = values[slot1];
final String val2 = values[slot2];
if (val1 == null) {
if (val2 == null) {
return 0;
}
return -1;
} else if (val2 == null) {
return 1;
}
return val1.compareTo(val2);
}
如果优先队列满了,则先和最低层的比较,如果大于最底层的则先替代最底层的,然后对优先队列重新排序
TopFieldCollector# OneComparatorNonScoringCollector. Collect的红色标识
@Override
public void collect(int doc) throws IOException {
++totalHits;
if (queueFull) {
if ((reverseMul * comparator.compareBottom(doc)) <= 0) {
// since docs are visited in doc Id order, if compare is 0, it means
// this document is largest than anything else in the queue, and
// therefore not competitive.
return;
}
// This hit is competitive - replace bottom element in queue & adjustTop
comparator.copy(bottom.slot, doc);
updateBottom(doc);
comparator.setBottom(bottom.slot); } else {
// Startup transient: queue hasn't gathered numHits yet
final int slot = totalHits - 1;
// Copy hit into queue
comparator.copy(slot, doc);
add(slot, doc, Float.NaN);
if (queueFull) {
comparator.setBottom(bottom.slot);
}
}
}
分享到:
相关推荐
Lucene 是一个开源的Java库,专门用于文本搜索,它提供了高效的索引和查询机制,使得开发者能够在Web应用中实现快速、精准的全文搜索功能。 **描述分析:** "用 Lucene 加速 Web 搜索应用程序的开发---实例代码" ...
本文将深入探讨一个名为“lucene_web”的项目,它是基于Lucene实现的一个Web应用程序实例,旨在帮助开发者更好地理解和运用Lucene进行Web开发。 首先,我们要明白Lucene的核心功能。Lucene提供了一套完整的搜索索引...
总的来说,"lucene+jdbcTemplate封装API+缓存实现索引精确刷新"这个项目展示了如何结合多种技术来优化数据检索流程,提高了系统的响应速度和数据一致性。这样的实践对于处理大数据量的系统尤为有价值,同时也展现了...
10. **内存和磁盘缓存**:为了提高性能,Lucene使用了缓存机制,如`BitSet`缓存和`TermInfo`缓存,分别用于存储文档存在性信息和词汇表信息。 总的来说,Lucene 3.0.1 API为开发者提供了丰富的功能和灵活性,使其...
5. **内存优化**:Lucene.Net在内存管理和缓存策略上进行了优化,能在大规模数据集上保持良好的性能。 6. **多线程支持**:Lucene.Net设计时考虑了多线程环境,支持并发索引和搜索操作,适用于高并发的Web应用。 7. ...
6. **倒排索引的优化**:在`MergePolicy`和`MergeScheduler`中,你可以看到Lucene如何决定何时和如何合并索引段,以保持索引的效率和空间利用率。 7. **近实时搜索(NRT)**:从3.0版本开始,Lucene引入了NRT机制,...
《Lucene实战》第二版是一本深入探讨Apache Lucene搜索引擎库的权威指南。...书中涵盖了从基础到进阶的各种主题,包括高级搜索技巧、索引优化以及如何解决实际开发中的问题,是学习和应用Lucene的宝贵资源。
本文将深入探讨Lucene 4.8的核心特性、使用方法以及相关的学习资料和案例,旨在帮助读者更好地理解和应用这一技术。 一、Lucene 4.8基础概念 1. 文档(Document):Lucene中的基本单位,用于存储信息,可以理解为...
Lucene是一个高性能、全文检索库,它是Java编写的一个开源项目,被广泛应用于各种版本的Java开发环境中,以实现高效、灵活的索引和搜索功能。Lucene的核心特性包括文本分析、索引构建、查询解析、排序以及结果评分等...
**Lucene封装与性能优化详解** Lucene是一个高性能、全文本搜索库,它为开发者提供了在应用程序中实现全文...以上是对Lucene封装和性能优化的概述,实际应用中还需要结合具体项目需求进行调整和优化,以达到最佳效果。
这本书深入浅出地讲解了如何利用Lucene进行高效的文本搜索和索引构建,是Java开发者理解和应用Lucene不可或缺的参考资料。 Lucene是一个强大的全文检索库,它允许开发者在应用程序中实现高级搜索功能,而无需从头...
- **结果排序**: Lucene 支持多种评分机制,如 TF-IDF,用于确定文档的相关性,从而对搜索结果进行排序。 - **结果返回**: 最后,返回给用户最相关的搜索结果。 ### 3. 文件和数据库支持 Lucene4 不仅能处理文本...
《Lucene 3.6 搜索实例解析》 Apache Lucene 是一个开源全文搜索引擎库,为开发者提供了在Java应用程序中实现高效...在实践中,理解并掌握Lucene的这些关键概念和流程,将有助于提升搜索体验,增强应用的核心竞争力。
在Java世界中,Lucene以其强大的搜索功能和灵活的API设计,成为开发搜索引擎应用的首选工具。它允许开发者快速构建全文索引,执行复杂的查询,并且支持多种文本分析器,以适应不同的语言和应用场景。 1. **Lucene...
### Lucene3源码分析知识点概述 #### 一、全文检索的基本原理 ##### 1....以上是对Lucene3源码分析的一些关键知识点总结,通过对这些概念和技术的理解,可以更好地掌握Lucene的工作原理及其应用。
在 Lucene 3.0 中,还支持评分函数和自定义排序。 6. **优化与更新**:索引的优化(Merge)操作可以合并多个段以减少磁盘空间占用和提高搜索性能。同时,Lucene 3.0 支持对已有索引的增删改操作,但需要注意的是,...
Lucene的核心功能包括文档索引、查询解析、评分和结果排序。在2.3.0版本中,这些功能得到了进一步增强,提升了性能和稳定性。源码分析是理解Lucene工作原理的关键,通过阅读源码,我们可以了解其内部数据结构、算法...
Lucene是一个高性能、全文本搜索库,它提供了完整的搜索功能,包括索引、查询和排序。在Lucene 5中,对性能和稳定性进行了优化,同时引入了新的特性和改进。Lucene的核心功能包括分词、倒排索引和布尔查询,这些都为...
5. **内存管理和性能优化**: Lucene.NET利用缓存和位集来提高性能,同时支持多线程和分布式搜索,使得在大规模数据集上的搜索依然快速。 6. **盘古分词**: 盘古分词是针对中文的分词库,它可以与Lucene.NET结合使用...
本文将围绕“Lucene5学习之拼音搜索”这一主题,详细介绍其拼音搜索的实现原理和实际应用。 首先,我们需要理解拼音搜索的重要性。在中文环境中,由于汉字的复杂性,用户往往习惯于通过输入词语的拼音来寻找信息。...