又见 Lucene

来源:互联网 发布:nginx反向代理服务器 编辑:程序博客网 时间:2024/05/16 19:42

今天很迷茫,迷茫了一天。


重新来聊聊 Lucene。


Lucene 是一个搜索工具。如果让你来实现搜索,你会在怎么做?

很简单,很自然的方法,暴力搜索。

但是,当被搜索量很大时,就可能花费很长的时间,导致用户体验不佳。(我并没有去实践,这是可能性很高的推测)


于是,Lucene 使用了一种思想,索引,而且是倒序索引。

相信,第一次看到的人都会觉得头大。(这种无缘无故冒出来的新的东西,让人崩溃)

http://jackyrong.iteye.com/blog/238940

http://www.cnblogs.com/end/archive/2013/01/22/2871581.html


很简单,也很公平,将大工作量的遍历和分析工作都在创建索引时完成。

这时能搜索哪些东西已经定下来,它们被称为 token。

Term 则是 field:token。


趁热打铁。

Document doc = new Document();doc.add(new TextField("path", file.getPath(), Field.Store.YES));

TextField 是分词的,可以中源码中看出。


默认的分词手段自然是按空格对英文分词,查询结果也很正确。

而且当我查询 "chinese hello" 也得到了的结果,这意味着不只能查询 term,也可也是它们的组合之类。


doc.add(new TextField("path", file.getPath(), Field.Store.NO));
当我将 Store 设置为 No 时,之前的查询结果还是成立的,只是当
 System.out.println(document.get("path"));
输出的就是 null 了,即无法获得原始的值了。

Document doc = new Document();doc.add(new StringField("path", file.getPath(), Field.Store.YES));    
我将 TextField 替换成了 StringField,而 StringField 是不分词的。

结果,查询 “hey” 没有匹配的结果。

这说明 STORE 对查询毫无影响,只是提供一种获得原始值的方法。


不过怎么会查不到呢? 说好是索引,不分词的。

A field that is indexed but not tokenized: the entire String value is indexed as a single token. 

API 中也说,将会把值作为一个单独的 token。

其实原因是 getPath 返回的是个相当长的路径。。。。

StringField 适合那些不需要分词的对象,比如 ID,姓名,电话号码。


TYPE_STORED.setIndexed(true);TYPE_STORED.setOmitNorms(true);TYPE_STORED.setIndexOptions(IndexOptions.DOCS_ONLY);TYPE_STORED.setStored(true);TYPE_STORED.setTokenized(false);TYPE_STORED.freeze();</span>

这是 StringField 代码中的一部分,4.0开始由 FieldType 来控制对 Fieldd 的处理。

而这里就是 FieldType 几个比较关键的方法。

是否索引,不索引就不能查询。

OmitNorms 这个有机会再说。

IndexOptions ,参考 FieldInfo 代码,有只记录文本信息,文本及文本出现频率等。

存储。

分词。

防止变动。


这篇就到这。 















0 0