Lucene.Net 2.3.1开发介绍 —— 三、索引(三)

释放双眼,带上耳机,听听看~!

3、Field配置所产生的效果

 索引数据,简单的代码,只要两个方法就搞定了,而在索引过程中用到的一些类里最简单,作用也不小的就是Field,接下来看看Field的各项设置都会有什么样的效果。

代码 3.1

 

Code

 1
/**/
///
 

<summary>

 2

///
 索引数据

 3

///
 

</summary>

 4
private
 
void
 Index()

 5

{

 6
    Analyzer analyzer 

 
new
 StandardAnalyzer();

 7
    IndexWriter writer 

 
new
 IndexWriter(
"
IndexDirectory
"
, analyzer, 
true
);

 8
    AddDocument(writer, 
"
我的祖国
"

"
英语单词
"
);

 9
    AddDocument(writer, 
"
祖国万岁
"

"
英语语法
"
);

10
    AddDocument(writer, 
"
祖国
"

"
英语单元
"
);

11
    AddDocument(writer, 
"
人民
"

"
单词测试
"
);

12
    writer.Optimize();

13
    writer.Close();

14
}

15

/**/
///
 

<summary>

16

///
 为索引准备数据

17

///
 

</summary>

18

///
 
<param name="writer">
索引实例

</param>

19

///
 
<param name="content">
需要索引的数据

</param>

20
void
 AddDocument(IndexWriter writer, 
string
 title, 
string
 content)

21

{

22
    Document document 

 
new
 Document();

23
    document.Add(
new
 Field(
"
title
"
, title, Field.Store.Yes, Field.Index.TOKENIZED));

24
    document.Add(
new
 Field(
"
content
"
, content, Field.Store.YES, Field.Index.TOKENIZED));

25
    writer.AddDocument(document);

26
}

 

 

代码3.1就是准备好的索引过程。运行,然后呢?这里要说到一个工具,luke(lukeall)这是一个java平台下的Lucene索引管理工具。抽空,我实现了一个简单的dotNet版本的,详细请查看 NLuke版本更新信息 。接下来的索引,会用这个软件对索引进行分析。

 

现在就可以开始调整AddDocument方法中Field实例化时的参数了,看看调整后会对索引造成什么样的影响。这里以title对应的Field为例。

 

3.1 Field.Stroe选项

这个选项有3个值,下面来分析下效果。

3.1.1 Field.Stroe.Yes

刚好,默认的就是这个。用这选项建完索引,然后用NLuke查看,发现,title这个字段有,而且有8个Term。切换到文档区域,发现文档的title有内容。这个选项表示的就是存储,所以,这些是正常状态。

3.1.2 Field.Stroe.No

title也有8个Term,但是文档中没有字段了。也就是说现在可以用这个字段来搜索,但是搜索结果Hits中,不能用Document实例的Get方法来取得字段的内容了。那就是字段内容没有被存储。

3.1.3 Field.Store.COMPRESS

设置为COMPRESS,报错了,错误信息“Compression support not configured”,是个配置错误。这个错误在SupportClass,CheckCompressionSupport方法被抛出。这里读取了一个配置文件,然后根据配置文件指定的类名来创建实例。这个类必须实现接口 SupportClass.CompressionSupport.ICompressionAdapter。在Lucene.Net中内置了一个“SharpZipLibAdapter”,但是需要有编译符号SHARP_ZIP_LIB才能编译进去。为了看看效果,所以给项目添加SHARP_ZIP_LIB符号,然后增加app.config配置文件,在appseting中添加Lucene.Net.CompressionLib.class键,值是SharpZipLibAdapter。然后下载 ICSharpCode.SharpZipLib.dll,这个dll才是真正实现压缩算法的。下载地址: 链接地址

把ICSharpCode.SharpZipLib.dll引入项目,就可以使用COMPRESS这个选项了。效果与Yes是一样的。

 

3.1.4 效果对比

对于Field.Stroe.Yes,产生字节大小是:627字节

Field.Stroe.COMPRESS是:661字节

Field.Stroe.No是:579字节

使用Field.Stroe.COMPRESS反而是占用空间最大,这不符合原先的设想。那是因为我们索引的文本太小,你可以试试看增加索引的内容,再对比小效果。

 

3.2 Field.Index选项

现在把Field.Stroe设置为Field.Stroe.Yes,接着来看看Field.Index的效果。

 

3.2.1 Field.Index.TOKENIZED

这个选项是用来控制分词的,TOKENIZED表明需要分词。运行后title有8个Term,没有问题。

3.2.2 Field.Index.UN_TOKENIZED

运行后只有4个Term,而且Term是原先写入的内容,和存储的完整内容没有区别。

3.2.3 Field.Index.NO

和预想的一样,title的Term一个也没有了。

3.2.4 Field.Index.NO_NORMS

效果似乎和Field.Index.UN_TOKENIZED一样,但是它把词条的附加信息全去掉了。比如,它将不再记录词的正太分布数据一类的东西。这样可以减少占用的空间。而且这个用法也有一个条件,就是只要开启,就要全部开启,否则会失效。比如索引了四条数据没使用NO_NORMS,而接下来的两条使用了NO_NORMS,那么前面四条的数据效果,那么接下来的两条数据实际上并没有产生NO_NORMS的效果。

3.2.5 效果分析

1,2,4三种情况虽然不同,但是都可以搜索,而第三种情况,也就是设置为NO,则不可以搜索。第一种情况,可以分词搜索,并且可以排序。而2,4则不能分词搜索,第四种情况不可以排序(不可以排序指,不能按照词出现的频率进行排序)。

 

从上面也可以看出,假设Field.Store设置为NO,而Field.Index也设置为NO,那就和没添加是一样的了。Field.Store是给你取完整数据用的,而Field.Index则是给搜索用的。在极端的情况下,可以设置Field.Store为NO,而Field.Index可以搜索,等取数据的时候再从数据源(比如数据库),它们中间有个关联法则,那样可以有效的减轻Lucene的工作压力。

 

3.3 Field.TermVector

Field.TermVector选项,现在工具还没实现这个功能,不过可以自己编码来实现。

 

代码 3.3.5.1

Code

 1
[Test]

 2

public
 
void
 TermVectorTest()

 3

{

 4
    IndexReader reader 

 IndexReader.Open(
"
IndexDirectory
"
);

 5
    
int
 numDoc 

 reader.NumDocs();

 6
    
for
 (
int
 i 

 
0
; i 
<
 numDoc; i
++
)

 7
    

{

 8
        Console.WriteLine(
"
Doc:#
"
 
+
 i 
+
 
"

"
);

 9
        Document doc 

 reader.Document(i);

10
        Field field 

 doc.GetField(
"
title
"
);

11
        Console.WriteLine(
"
是否被索引:
"
 
+
 field.IsIndexed());

12
        Console.WriteLine(
"
是否被存储:
"
 
+
 field.IsStored());

13
        Console.WriteLine(
"
是否存储开始位置:
"
 
+
 field.IsStorePositionWithTermVector());

14
        Console.WriteLine(
"
是否存储结束位置:
"
 
+
 field.IsStoreOffsetWithTermVector());

15
        Console.WriteLine(
"
是否保存了向量:
"
 
+
 field.IsTermVectorStored());

16
        Console.WriteLine(
"
是否分词:
"
 
+
 field.IsTokenized());

17
        Console.WriteLine(
"

"
);

18
    }

19
    reader.Close();

20
}

 

设置Field.TermVector后,可以用代码3.3.5.1检查效果。你可以自己去试试。

给TA打赏
共{{data.count}}人
人已打赏
安全运维

OpenSSH-8.7p1离线升级修复安全漏洞

2021-10-23 10:13:25

安全运维

设计模式的设计原则

2021-12-12 17:36:11

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索