spi在lucene中的应用

针对lucene-4713这个issue。梳理了下spi相关知识点以及它在lucene中的应用 。

 

4.2中solr对docvalues支持学习

From Evernote:

4.2中solr对docvalues支持学习

1. 入口:

          对solr来说,schema是任何新增数据类型支持的一个入口。

          对docvalues的支持也不例外,如果某个field是支持docvalues,应该是在schema中体现。

      实现的体现是:

   

 

   相比之前的field定义,这里多了 docValues=”true”这一property.

2. domain级别的支持

   描述这些property的类是:

    FieldProperties.java 

          protected  final  static int STORE_OFFSETS      = 0×00004000;

          添加了: protected final static int DOC_VALUES          = 0×00008000;

          这里采用了bit values for boolean field properties

          这比一般设计时采用的为每个boolean variable 采用一个field要好多了,节省了内存.同时在操作上也会更有灵活性。

   FieldType, SchemaField 这两个子类, schemaField这是一个为field各方面具体提供接口的类,因此肯定会有判断是否支持docvalues这类的方法。 schemaField 对应于schema文件中的field element.

              FieldType 及其子类 是具体的各个field描述。对应于schema文件中field type element。

              FieldType 一个重要功能是它会根据 schemaField生成,对应的value 生成 indexableField

              这一个方法 就把 solr中的schemaField, FieldType, lucene中的IndexableField这三者紧密地联系在了一起。

    

    DocumentBuilder 因为solr是在lucene之上做的,其本身有对filed的定义,document的定义,因此对schema中定义的改动,很容易触及到这个中间者的变化。

3. Add时的支持 

    

    提交的xml文件,包含一个document的信息,

==>对于每个field解释成SolrInputField(name , value, + boost)==> 组合成 SolrInputDocument ==> Docement (AddUpdateCommand-> DocumentBuilder(SolrInputDocument,IndexSchema))       这里一个关键信息是IndexSchema, 因为可以根据field name从index schema中取到 SchemaField
    进而可以得到这个field的type。 这部分业务对象的组织是和配置文件紧密结合在一志的。
    整个schema.xml文件对应于  <=====> IndexSchema
                 <=======> SchemaField
  <=======> FieldType 

      

    这个流程其实也和上述分析的domain修改有一定的内在联系。

    因此关键修改点就在 几个支持docvalues的 具体FieldType 的createField 方法 上。

    在这里一个关键动作就是把 solr FieldType上的配置信息 映射到 lucene级的 FieldType上。 

  note:

        在具体的fieldType的createFields方法中,如果当前field 支持docvalues,会生成两个IndexableField

        一个是无docvalues项的indexableField

        另一个是NumericDocValuesField , 为什么会这样处理呢?

4. query时的支持

    solr 通过父类拿到的都是 doc id

    几个关键点:

    如上述例子中,配置了 intdv为 int 并且支持docvalues,

    在一整个内部,如何来区分这些不同呢?

    也就是说如果在 一个query中,如果使用 intdv 进行sort, 这时对intdv是否支持docvalues放在哪一层?

    

    针对sort这场景, 关心的是对应docid 的doc 中intdv的值是多少, 如果不是docvalues,以之前的经验,这个 value是来自fieldcache,

   如果是docvalues呢?毫无疑问 这个值应该来自docvalues。

   可以考虑使用fieldcache的统一接口,但在返回值时,屏蔽掉是来自feildcach,还是单独的docvalues。

   在fieldCacheImpl的getLongs(…) , getFloats(…), getInts(….) 这些接口中,就是体现了这类设计。

   因此在fieldComparator中,引用就很方便,可以屏蔽底层细节了

   

    @Override

    public FieldComparator setNextReader(AtomicReaderContext context) throws IOException {
      // NOTE: must do this before calling super otherwise
      // we compute the docsWithField Bits twice!
      currentReaderValues = FieldCache.DEFAULT.getFloats(context.reader(), field, parser, missingValue != null);
      returnsuper.setNextReader(context);

    } 

facet场景: