防止忘记的最好的方法就是记下来。

这是一段最简单的搜索代码:

public void Search()
{
    var dir=FSDirectory.Open(new DirectoryInfo("xxx"));
    var searcher = new IndexSearcher(dir, true);
    var query = new TermQuery(new Term("Title", "jinzhao"));
    var tops=searcher.Search(query,100);
    foreach(var top in tops)
    {
        var doc=searcher.Doc(top);
        Output(doc);
    }
}

红色的一句话就返回了一个完整document,是search内部的IndexReader(Lucene.Net.Index.IndexReader)返回的document,方法如下:

public abstract Document Document(int n, FieldSelector fieldSelector);

下面是这个类的实现:

他们的关系如下:

MultiReader和ParallelReader维护了IndexReader的一个集合(这些IndexReader可能由下面几重实现,但是不包含SegmentReader),封装了访问多个reader的方式,原理就是lucene里最常见的偏移的方式;

DirectoryReader等除SegmentReader外模拟的是一个目录,就像索引文件夹一样,它维护了一组SegmentReader的实现,原理如上;

SegmentReader是读取文档的最小单位它不再维护任何子的IndexReader,接收到ID后就会读取通过public sealed class FieldsReader 读取这个文档的字段(Lucene的核心就是文档,一个文档由若干字段组成),这里加载方式有立即加载、立即加载指定字段、懒加载等其它几种,方法如下:

public /*internal*/ Document Doc(int n, FieldSelector fieldSelector)
{
    SeekIndex(n);
    long position = indexStream.ReadLong();
    fieldsStream.Seek(position);
     
    Document doc = new Document();
    int numFields = fieldsStream.ReadVInt();
    for (int i = 0; i < numFields; i++)
    {
        int fieldNumber = fieldsStream.ReadVInt();
        FieldInfo fi = fieldInfos.FieldInfo(fieldNumber);
        FieldSelectorResult acceptField = fieldSelector == null?FieldSelectorResult.LOAD:fieldSelector.Accept(fi.name);
         
        byte bits = fieldsStream.ReadByte();
        System.Diagnostics.Debug.Assert(bits <= FieldsWriter.FIELD_IS_COMPRESSED + FieldsWriter.FIELD_IS_TOKENIZED + FieldsWriter.FIELD_IS_BINARY);
         
        bool compressed = (bits & FieldsWriter.FIELD_IS_COMPRESSED) != 0;
        bool tokenize = (bits & FieldsWriter.FIELD_IS_TOKENIZED) != 0;
        bool binary = (bits & FieldsWriter.FIELD_IS_BINARY) != 0;
        //TODO: Find an alternative approach here if this list continues to grow beyond the
        //list of 5 or 6 currently here.  See Lucene 762 for discussion
        if (acceptField.Equals(FieldSelectorResult.LOAD))
        {
            AddField(doc, fi, binary, compressed, tokenize);
        }
        else if (acceptField.Equals(FieldSelectorResult.LOAD_FOR_MERGE))
        {
            AddFieldForMerge(doc, fi, binary, compressed, tokenize);
        }
        else if (acceptField.Equals(FieldSelectorResult.LOAD_AND_BREAK))
        {
            AddField(doc, fi, binary, compressed, tokenize);
            break; //Get out of this loop
        }
        else if (acceptField.Equals(FieldSelectorResult.LAZY_LOAD))
        {
            AddFieldLazy(doc, fi, binary, compressed, tokenize);
        }
        else if (acceptField.Equals(FieldSelectorResult.SIZE))
        {
            SkipField(binary, compressed, AddFieldSize(doc, fi, binary, compressed));
        }
        else if (acceptField.Equals(FieldSelectorResult.SIZE_AND_BREAK))
        {
            AddFieldSize(doc, fi, binary, compressed);
            break;
        }
        else
        {
            SkipField(binary, compressed);
        }
    }
     
    return doc;
}

标红的是一个IndexInput的实现,它是具体读取的方法,实现一般在存储类中以嵌套公开的方式实现,比如此处例子的实现如下:

public /*protected internal*/class SimpleFSIndexInput : BufferedIndexInput, System.ICloneable
{
    protected internal class Descriptor : System.IO.BinaryReader
    {
        // remember if the file is open, so that we don't try to close it
        // more than once
        protected internal volatile bool isOpen;
        internal long position;
        internal long length;
        public Descriptor(/*FSIndexInput enclosingInstance,*/ System.IO.FileInfo file, System.IO.FileAccess mode)
            : base(new System.IO.FileStream(file.FullName, System.IO.FileMode.Open, mode, System.IO.FileShare.ReadWrite))
        {
            isOpen = true;
            length = file.Length;
        }
        public override void Close()
        {
            if (isOpen)
            {
                isOpen = false;
                base.Close();
            }
        }
        ~Descriptor()
        {
            try
            {
                Close();
            }
            finally
            {
            }
        }
    }

可以看到最后字段由System.IO.BinaryReader到文件中读取。

完。

本文转自today4king博客园博客,原文链接:http://www.cnblogs.com/jinzhao/archive/2012/06/05/2537068.html,如需转载请自行联系原作者

Lucene.Net中 FSDirectory存储方式下一个 Document是如何得到的相关推荐

  1. C/C++中涉及存储方式的关键字:auto,static,register,extern2009-01-22 11:23auto关键字:

    C/C++中涉及存储方式的关键字:auto,static,register,extern 2009-01-22 11:23 auto关键字: auto对象和变量被存储在栈中,它的生命周期仅存在于它的声 ...

  2. c++全局类对象_C++ 类在内存中的存储方式(一)

    说了这么久的 C++ 终于说到类了,还是从内存出发来讨论一下 C++ 的类在内存中的存储方式(之前写过一篇内存对齐的文章,类同样在一定程度上遵循内存对齐原则,不过比结构体复杂一下) 如有侵权,请联系 ...

  3. C语言的数据类型大全,整型数据在内存中的存储方式

    一.数据类型 通过长时间的学习C语言以及代码的编写,我掌握了很多很多的数据类型,下面就给大家罗列一下. 1.内置数据类型 char        //字符数据类型--                  ...

  4. 【C语言】浮点型数据在内存中的存储方式

    目录 一. 前言 二. 问题的引出 三. 两类浮点型数据(float.double)在内存中的存储方式 3.1 两类浮点型数据的存储模型 3.1.1 浮点型数据数值读取的通用模型 3.1.2 floa ...

  5. IEEE754标准: 浮点数在内存中的存储方式

    一. 什么是IEEE754标准 我们知道, 计算机内部实际上只能存储或识别二进制. 在计算机中, 我们日常所使用的文档, 图片, 数字等, 在储存时, 实际上都要以二进制的形式存放在内存或硬盘中, 内 ...

  6. 初探元宇宙存储,数据存储市场下一个爆点?

    2021年,元宇宙一词火爆全球,成为全社会关注的焦点. 除了在游戏和娱乐领域大有前途之外,元宇宙还能干嘛?让我们来看看元宇宙在医疗领域如何小试牛刀. "把二维CT切片组合成三维立体的'全息数 ...

  7. C/C++浮点数在内存中的存储方式《转》

    那天有人在汇编群里有人问了一个 #include <iostream> #include <stdio.h> using namespace std; int main() { ...

  8. 【chatGPT】01 数组、二维数组在不同语言中的存储方式

    问:数组在C++中的存储方式是什么?Java呢?Python呢?可以举例吗? C++ 在C++中,数组是连续分配的内存单元,具有相同的类型和大小. C++会将数组的第一个元素存储在指向数组的指针中,因 ...

  9. JavaScript中数据在内存中的存储方式

    JavaScript中数据在内存中的存储方式 1.js数据类型分类 简单数据类型:Number.String.Boolean.Undefined.Null 复杂数据类型:Object.Array.Fu ...

  10. c语言double数据存储形式,C语言 float、double数据在内存中的存储方式

    float在内存中占4个字节(32bit),32bit=符号位(1bit)+指数位(8bit)+底数位(23bit) 指数部分 指数位占8bit,可以表示数值的范围是0-(表示0~255一共256个数 ...

最新文章

  1. 比特币的货币属性是什么?
  2. BLE-NRF51822教程5-静态密码设置
  3. 在 Kubernetes 上弹性深度学习训练利器 -- Elastic Training Operator
  4. Linux常用初级指令介绍
  5. 嵌入式数据库sqlite在ARM上的的移植和使用
  6. 震惊,PostGIS还可以这样用!!!
  7. python制作会动的表情包_Python自动生成表情包,python在手,从此斗图无敌手
  8. 一张小柴胡汤打天下- 四川名医马有度
  9. 数据库期末总结笔记( 零基础 )
  10. 基础连接已关闭解决办法_解决|罗技蓝牙键盘连接ipad后打不出字?
  11. # 你也可以在你的微信 or QQ头像添加小国旗了,超简单!
  12. (转)Openbravo ERP介绍(二)
  13. 编程语言介绍以及特点
  14. bin文件用cad打开_bin文件怎么用cad打开
  15. SpaceX SN8飞船爆炸,马斯克:已拿到全部所需数据,火星,我们来了!
  16. R语言笔记1:t检验和Wilcoxon检验
  17. 浏览器tab页签上的title图标favicon.icon
  18. 最通俗易懂的OSPF五种报文+七种状态
  19. 个人开发者轻松接入支付回调
  20. Android 设置投影效果

热门文章

  1. AC日记——幸运号码 51nod 1043
  2. Python2.7学习笔记-定义函数、filter/map/reduce/lambda
  3. cf446C DZY Loves Fibonacci Numbers
  4. 在Windos上安装Nginx
  5. springmvc中校验框架(hibernate)
  6. Python工程师面试题目
  7. Git:常用命令记录
  8. Oracle 恢复删除的表
  9. pytest框架学习
  10. xcode 4.2 开发2——TabelView