lucene搜索之facet查询原理和facet查询实例——TODO

简介:

转自:http://www.lai18.com/content/7084969.html

Facet说明

我们在浏览网站的时候,经常会遇到按某一类条件查询的情况,这种情况尤以电商网站最多,以天猫商城为例,我们选择某一个品牌,系统会将该品牌对应的商品展示出来,效果图如下:


如上图,我们关注的是品牌,选购热点等方面,对于类似的功能我们用lucene的term查询当然可以,但是在数据量特别大的情况下还用普通查询来实现显然会因为FSDirectory.open等耗时的操作造成查询效率的低下,同时普通查询是全部document都扫描一遍,这样显然造成了查询效率低;

lucene提供了facet查询用于对同一类的document进行聚类化,这样在查询的时候先关注某一个方面,这种显然缩小了查询范围,进而提升了查询效率;

facet模块提供了多个用于处理facet的统计和值处理的方法;

要实现facet的功能,我们需要了解facetField,FacetField定义了dim和此field对应的path,需要特别注意的是我们在做facetField索引的时候,需要事先调用FacetsConfig.build(Document);

FacetField的indexOptions设置为了DOCS_AND_FREQS_AND_POSITIONS的,即既索引又统计出现的频次和出现的位置,这样做主要是为了方便查询和统计;

相应的在存储的时候我们需要利用FacetsConfig和DirectoryTaxonomyWriter;

DirectoryTaxonomyWriter用来利用Directory来存储Taxono信息到硬盘;

DirectoryTaxonomyWriter的构造器如下:

复制代码
public DirectoryTaxonomyWriter(Directory directory, OpenMode openMode,
      TaxonomyWriterCache cache) throws IOException {

    dir = directory;
    IndexWriterConfig config = createIndexWriterConfig(openMode);
    indexWriter = openIndexWriter(dir, config);

    // verify (to some extent) that merge policy in effect would preserve category docids 
    assert !(indexWriter.getConfig().getMergePolicy() instanceof TieredMergePolicy) : 
      "for preserving category docids, merging none-adjacent segments is not allowed";
    
    // after we opened the writer, and the index is locked, it's safe to check
    // the commit data and read the index epoch
    openMode = config.getOpenMode();
    if (!DirectoryReader.indexExists(directory)) {
      indexEpoch = 1;
    } else {
      String epochStr = null;
      Map<String, String> commitData = readCommitData(directory);
      if (commitData != null) {
        epochStr = commitData.get(INDEX_EPOCH);
      }
      // no commit data, or no epoch in it means an old taxonomy, so set its epoch to 1, for lack
      // of a better value.
      indexEpoch = epochStr == null ? 1 : Long.parseLong(epochStr, 16);
    }
    
    if (openMode == OpenMode.CREATE) {
      ++indexEpoch;
    }
    
    FieldType ft = new FieldType(TextField.TYPE_NOT_STORED);
    ft.setOmitNorms(true);
    parentStreamField = new Field(Consts.FIELD_PAYLOADS, parentStream, ft);
    fullPathField = new StringField(Consts.FULL, "", Field.Store.YES);

    nextID = indexWriter.maxDoc();

    if (cache == null) {
      cache = defaultTaxonomyWriterCache();
    }
    this.cache = cache;

    if (nextID == 0) {
      cacheIsComplete = true;
      // Make sure that the taxonomy always contain the root category
      // with category id 0.
      addCategory(new FacetLabel());
    } else {
      // There are some categories on the disk, which we have not yet
      // read into the cache, and therefore the cache is incomplete.
      // We choose not to read all the categories into the cache now,
      // to avoid terrible performance when a taxonomy index is opened
      // to add just a single category. We will do it later, after we
      // notice a few cache misses.
      cacheIsComplete = false;
    }
}
复制代码

由上述代码可知,DirectoryTaxonomyWriter先打开一个IndexWriter,在确保indexWriter打开和locked的前提下,读取directory对应的segments中需要提交的内容,如果读取到的内容为空,说明是上次的内容,设置indexEpoch为1,接着对cache进行设置;判断directory中是否还包含有document,如果有设置cacheIsComplete为false,反之为true;













本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/bonelee/p/6347274.html,如需转载请自行联系原作者

相关文章
|
4月前
|
存储 搜索推荐 API
探究:Elasticsearch 文档的 _id 是 Lucene 的 docid 吗?
【8月更文挑战第31天】在深入探索Elasticsearch(简称ES)这一强大的搜索引擎时,了解其底层存储机制——特别是与Lucene的关系,对于优化查询性能、设计高效的数据模型至关重要。其中,一个常见且容易引发误解的问题便是:Elasticsearch中文档的_id字段是否直接等同于Lucene的docid?本文将通过图文并茂的方式,详细剖析这一问题,帮助读者理解两者之间的微妙关系。
108 0
|
自然语言处理 索引
09 Lucene索引库查询 - query子类查询
09 Lucene索引库查询 - query子类查询
50 0
|
Java Apache 索引
10 Lucene索引库查询 - queryparser查询
10 Lucene索引库查询 - queryparser查询
121 0
|
SQL Java
白话Elasticsearch04- 结构化搜索之使用terms query搜索多个值以及多值搜索结果优化
白话Elasticsearch04- 结构化搜索之使用terms query搜索多个值以及多值搜索结果优化
531 0
|
SQL
白话Elasticsearch05- 结构化搜索之使用range query来进行范围过滤
白话Elasticsearch05- 结构化搜索之使用range query来进行范围过滤
127 0
|
SQL JSON 自然语言处理
白话Elasticsearch01- 结构化搜索之使用term query来搜索数据
白话Elasticsearch01- 结构化搜索之使用term query来搜索数据
307 0
|
Java Spring
spring data solr实现关键字搜索+高亮显示+分组查询
spring data solr实现关键字搜索+高亮显示+分组查询
285 0
spring data solr实现关键字搜索+高亮显示+分组查询
|
缓存 Java
Elasticsearch Query DSL之Compound queries(复合查询)
Elasticsearch Query DSL之Compound queries(复合查询)
Elasticsearch Query DSL之Compound queries(复合查询)
|
JavaScript Java
DataTables单纯的分页 不排序 没有默认搜索
憋了好几天看了中文和英文的文档,终于把分页搞出来了,先前一直纠结这个页码和页容量怎么传的,其实不用纠结这个,会自动识别。
262 0
|
自然语言处理 索引 关系型数据库
Elasticsearch结构化搜索_在案例中实战使用term filter来搜索数据
根据用户ID、是否隐藏、帖子ID、发帖日期来搜索帖子
1698 0