zoukankan      html  css  js  c++  java
  • 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;

  • 相关阅读:
    「2019冬令营提高组」原样输出
    FJWC2019
    P2763 试题库问题
    P3979 遥远的国度
    P2754 [CTSC1999]家园
    P1251 餐巾计划问题
    P1382 楼房
    P1384 幸运数与排列
    P4294 [WC2008]游览计划
    P3345 [ZJOI2015]幻想乡战略游戏
  • 原文地址:https://www.cnblogs.com/bonelee/p/6347274.html
Copyright © 2011-2022 走看看