Lucene 中的Tokenizer, TokenFilter学习
https://brandnewuser.iteye.com/blog/2305140
- java.io.Reader -> com.chenlb.mmseg4j.solr.MMSegTokenizer -> SynonymFilter -> StopFilter -> WordDelimiterFilter -> LowerCaseFilter -> RemoveDuplicatesTokenFilter
- <fieldType name="nametext" class="solr.TextField">
- <analyzer type="index">
- <tokenizer class="solr.StandardTokenizerFactory"/>
- <filter class="solr.LowerCaseFilterFactory"/>
- <filter class="solr.KeepWordFilterFactory" words="keepwords.txt"/>
- <filter class="solr.SynonymFilterFactory" synonyms="syns.txt"/>
- </analyzer>
- <analyzer type="query">
- <tokenizer class="solr.StandardTokenizerFactory"/>
- <filter class="solr.LowerCaseFilterFactory"/>
- </analyzer>
- </fieldType>
- public class SynonymFilter extends TokenFilter {
- private static final String TOKEN_TYPE_SYNONYM = "SYNONYM";
- private Stack<String> synonymStack;
- private SynonymEngine synonymEngine;
- private AttributeSource.State current;
- private final CharTermAttribute bytesTermAttribute;
- private final PositionIncrementAttribute positionIncrementAttribute;
- /**
- * Construct a token stream filtering the given input.
- *
- * @param input
- */
- protected SynonymFilter(TokenStream input, SynonymEngine synonymEngine) {
- super(input);
- this.synonymEngine = synonymEngine;
- synonymStack = new Stack<>();
- this.bytesTermAttribute = addAttribute(CharTermAttribute.class);
- this.positionIncrementAttribute = addAttribute(PositionIncrementAttribute.class);
- }
- @Override
- public boolean incrementToken() throws IOException {
- if (!synonymStack.isEmpty()) {
- String syn = synonymStack.pop();
- restoreState(current);
- // bytesTermAttribute.setBytesRef(new BytesRef(syn.getBytes()));
- // bytesTermAttribute.resizeBuffer(0);
- bytesTermAttribute.append(syn);
- positionIncrementAttribute.setPositionIncrement(0);
- return true;
- }
- if (!input.incrementToken()) {
- return false;
- }
- if (addAliasesToStack()) {
- current = captureState();
- }
- return true;
- }
- private boolean addAliasesToStack() throws IOException {
- String[] synonyms = synonymEngine.getSynonyms(bytesTermAttribute.toString());
- if (synonyms == null) {
- return false;
- }
- for (String synonym : synonyms) {
- synonymStack.push(synonym);
- }
- return true;
- }
- }
- public class SynonymAnalyzer extends Analyzer {
- @Override
- protected TokenStreamComponents createComponents(String fieldName) {
- StandardTokenizer source = new StandardTokenizer();
- return new TokenStreamComponents(source, new SynonymFilter(new StopFilter(new LowerCaseFilter(source),
- new CharArraySet(StopAnalyzer.ENGLISH_STOP_WORDS_SET, true)), new TestSynonymEngine()));
- }
- }
- public interface SynonymEngine {
- String[] getSynonyms(String s) throws IOException;
- }
- public class TestSynonymEngine implements SynonymEngine {
- public static final Map<String, String[]> map = new HashMap<>();
- static {
- map.put("quick", new String[]{"fast", "speedy"});
- }
- @Override
- public String[] getSynonyms(String s) throws IOException {
- return map.get(s);
- }
- }
- public static void main(String[] args) throws IOException {
- SynonymAnalyzer analyzer = new SynonymAnalyzer();
- TokenStream tokenStream = analyzer.tokenStream("contents", new StringReader("The quick brown fox"));
- tokenStream.reset();
- CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
- OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
- PositionIncrementAttribute positionIncrementAttribute =
- tokenStream.addAttribute(PositionIncrementAttribute.class);
- TypeAttribute typeAttribute = tokenStream.addAttribute(TypeAttribute.class);
- int position = 0;
- while (tokenStream.incrementToken()) {
- int positionIncrement = positionIncrementAttribute.getPositionIncrement();
- if (positionIncrement > 0) {
- position += positionIncrement;
- System.out.println();
- System.out.print(position + " : ");
- }
- System.out.printf("[%s : %d -> %d : %s]", charTermAttribute.toString(), offsetAttribute.startOffset(), offsetAttribute.endOffset(),
- typeAttribute.type());
- }
- 2 : [quick : 4 -> 9 : <ALPHANUM>][quickspeedy : 4 -> 9 : <ALPHANUM>][quickfast : 4 -> 9 : <ALPHANUM>]
- 3 : [brown : 10 -> 15 : <ALPHANUM>]
- 4 : [fox : 16 -> 19 : <ALPHANUM>]
- <fieldtype name="textComplex" class="solr.TextField" positionIncrementGap="100">
- <analyzer type="index">
- <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="/Users/mazhiqiang/develop/tools/solr-5.5.0/server/solr/product/conf/dic" />
- <filter class="solr.StopFilterFactory" ignoreCase="false" words="stopwords.txt"/>
- <filter class="solr.WordDelimiterFilterFactory"/>
- <filter class="solr.LowerCaseFilterFactory"/>
- <filter class="solr.NGramFilterFactory" minGramSize="1" maxGramSize="20"/>
- <filter class="solr.StandardFilterFactory"/>
- </analyzer>
- <analyzer type="query">
- <tokenizer class="com.chenlb.mmseg4j.solr.MMSegTokenizerFactory" mode="complex" dicPath="/Users/mazhiqiang/develop/tools/solr-5.5.0/server/solr/product/conf/dic" />
- <filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/>
- <filter class="solr.StopFilterFactory" ignoreCase="false" words="stopwords.txt"/>
- <filter class="solr.WordDelimiterFilterFactory"/>
- <filter class="solr.LowerCaseFilterFactory"/>
- <!-- <filter class="solr.EdgeNGramFilterFactory" minGramSize="1" maxGramSize="20"/> -->
- <filter class="solr.RemoveDuplicatesTokenFilterFactory"/>
- </analyzer>
- </fieldtype>
- String line = null;
- while ((line = in.readLine()) != null) {
- if (line.length() == 0 || line.charAt(0) == '#') {
- continue; // ignore empty lines and comments
- }
- // TODO: we could process this more efficiently.
- String sides[] = split(line, "=>");
- if (sides.length > 1) { // explicit mapping
- if (sides.length != 2) {
- throw new IllegalArgumentException("more than one explicit mapping specified on the same line");
- }
- String inputStrings[] = split(sides[0], ",");
- CharsRef[] inputs = new CharsRef[inputStrings.length];
- for (int i = 0; i < inputs.length; i++) {
- inputs[i] = analyze(unescape(inputStrings[i]).trim(), new CharsRefBuilder());
- }
- String outputStrings[] = split(sides[1], ",");
- CharsRef[] outputs = new CharsRef[outputStrings.length];
- for (int i = 0; i < outputs.length; i++) {
- outputs[i] = analyze(unescape(outputStrings[i]).trim(), new CharsRefBuilder());
- }
- // these mappings are explicit and never preserve original
- for (int i = 0; i < inputs.length; i++) {
- for (int j = 0; j < outputs.length; j++) {
- add(inputs[i], outputs[j], false);
- }
- }
- @Override
- protected TokenStreamComponents createComponents(String fieldName) {
- Tokenizer tk = tokenizer.create();
- TokenStream ts = tk;
- for (TokenFilterFactory filter : filters) {
- ts = filter.create(ts);
- }
- return new TokenStreamComponents(tk, ts);
- }
- @Override
- public TokenStream create(TokenStream input) {
- // if the fst is null, it means there's actually no synonyms... just return the original stream
- // as there is nothing to do here.
- return map.fst == null ? input : new SynonymFilter(input, map, ignoreCase);
- }
StandardAnalyzer |
1 : [please : 0 -> 6 : <ALPHANUM>]
2 : [email : 7 -> 12 : <ALPHANUM>]
3 : [clark.ma : 13 -> 21 : <ALPHANUM>]
4 : [gmail.com : 22 -> 31 : <ALPHANUM>]
6 : [09 : 35 -> 37 : <NUM>]
7 : [re:aa : 39 -> 44 : <ALPHANUM>]
8 : [bb : 45 -> 47 : <ALPHANUM>]
|
去除空格,标点符号,@;
|
ClassicAnalyzer |
1 : [please : 0 -> 6 : <ALPHANUM>]
2 : [email : 7 -> 12 : <ALPHANUM>]
3 : [clark.ma@gmail.com : 13 -> 31 : <EMAIL>]
5 : [09 : 35 -> 37 : <ALPHANUM>]
6 : [re : 39 -> 41 : <ALPHANUM>]
7 : [aa : 42 -> 44 : <ALPHANUM>]
8 : [bb : 45 -> 47 : <ALPHANUM>]
|
能够识别互联网域名和email地址, |
LetterTokenizer |
1 : [Please : 0 -> 6 : word]
2 : [email : 7 -> 12 : word]
3 : [clark : 13 -> 18 : word]
4 : [ma : 19 -> 21 : word]
5 : [gmail : 22 -> 27 : word]
6 : [com : 28 -> 31 : word]
7 : [by : 32 -> 34 : word]
8 : [re : 39 -> 41 : word]
9 : [aa : 42 -> 44 : word]
10 : [bb : 45 -> 47 : word]
|
丢弃掉所有的非文本字符 |
KeywordTokenizer |
1 : [Please email clark.ma@gmail.com by 09, re:aa-bb : 0 -> 47 : word]
|
将整个文本当做一个词元 |
LowerCaseTokenizer |
1 : [please : 0 -> 6 : word]
2 : [email : 7 -> 12 : word]
3 : [clark : 13 -> 18 : word]
4 : [ma : 19 -> 21 : word]
5 : [gmail : 22 -> 27 : word]
6 : [com : 28 -> 31 : word]
7 : [by : 32 -> 34 : word]
8 : [re : 39 -> 41 : word]
9 : [aa : 42 -> 44 : word]
10 : [bb : 45 -> 47 : word]
|
对其所有非文本字符,过滤空格,标点符号,将所有的大写转换为小写 |
NGramTokenizer |
可以定义最小minGramSize(default=1), 最大切割值maxGramSize(default=2),生成的词元较多。
假设minGramSize=2, maxGramSize=3,输入abcde,输出:ab abc abc bc bcd cd cde
|
读取字段并在给定范围内生成多个token |
PathHierachyTokenizer |
c:\my document\filea\fileB,new PathHierarchyTokenizer('\\', '/')
1 : [c: : 0 -> 2 : word][c:/my document : 0 -> 14 : word][c:/my document/filea : 0 -> 20 : word][c:/my document/filea/fileB : 0 -> 26 : word]
|
使用新的文件目录符去代替文本中的目录符 |
PatternTokenizer |
需要两个参数,pattern正则表达式,group分组。
pattern=”[A-Z][A-Za-z]*” group=”0″
输入: “Hello. My name is Inigo Montoya. You killed my father. Prepare to die.”
输出: “Hello”, “My”, “Inigo”, “Montoya”, “You”, “Prepare”
|
进行正则表达式分组匹配 |
UAX29URLEmailTokenizer |
1 : [Please : 0 -> 6 : <ALPHANUM>]
2 : [email : 7 -> 12 : <ALPHANUM>]
3 : [clark.ma@gmail.com : 13 -> 31 : <EMAIL>]
4 : [by : 32 -> 34 : <ALPHANUM>]
5 : [09 : 35 -> 37 : <NUM>]
6 : [re:aa : 39 -> 44 : <ALPHANUM>]
7 : [bb : 45 -> 47 : <ALPHANUM>]
|
去除空格和标点符号,但保留url和email连接 |
ClassicFilter | “I.B.M. cat’s can’t” ==> “I.B.M”, “cat”, “can’t” | 经典过滤器,可以过滤无意义的标点,需要搭配ClassicTokenizer使用 |
ApostropheFilter |
1 : [abc : 0 -> 3 : <ALPHANUM>]
2 : [I.B.M : 4 -> 9 : <ALPHANUM>]
3 : [cat : 10 -> 15 : <ALPHANUM>]
4 : [can : 16 -> 21 : <ALPHANUM>]
|
省略所有的上撇号 |
LowerCaseFilter |
1 : [i.b.m : 0 -> 5 : <ALPHANUM>]
2 : [cat's : 6 -> 11 : <ALPHANUM>]
3 : [can't : 12 -> 17 : <ALPHANUM>]
|
转换成小写 |
TypeTokenFilter |
<filter class=”solr.TypeTokenFilterFactory” types=”email_type.txt” useWhitelist=”true”/>
如果email_type.txt设置为ALPHANUM,会保留该类型的所有分析结果,否则会被删除掉
|
给定一个文件并设置成白名单还是黑名单,只有符合条件的type才能被保留 |
TrimFilter | 去掉空格 | |
TruncateTokenFilter |
1 : [I.B : 0 -> 5 : <ALPHANUM>]
2 : [cat : 6 -> 11 : <ALPHANUM>]
3 : [can : 12 -> 17 : <ALPHANUM>]
|
截取文本长度,左边为prefixLength=3 |
PatternCaptureGroupFilter | 可配置属性pattern和preserve_original(是否保留原文) | 从输入文本中保留能够匹配正则表达式的 |
PatternReplaceFilter | ||
StopFilter | 创建一个自定义的停词词库列表,过滤器遇到停词就直接过滤掉 | |
KeepWordFilter | 与StopFilter的含义正好相反 | |
LengthFilter | 设置一个最小值min和最大值max | 为词元的长度设置在一个固定范围 |
WordDelimiterFilter |
A:-符号 wi-fi 变成wi fi
其他参数
splitOnCaseChange=”1″ 默认1,关闭设为0 规则B generateWordParts=”1″ 默认1 ,对应规则AB generateNumberParts=”1″ 默认1 对应规则F catenateWords=”1″ 默认0 对应规则A splitOnNumerics=”1″ 默认1,关闭设0 规则C stemEnglishPossessive 默认1,关闭设0 规则E catenateNumbers=”1″ 默认0 对应规则G catenateAll=”1″ 默认0 对应规则 H preserveOriginal=”1″ 默认0 对词元不做任何修改 除非有其他参数改变了词元
protected=”protwords.txt” 指定这个单词列表的单词不被修改
|
通过分隔符分割单元 |
转载于:https://www.cnblogs.com/davidwang456/articles/10470938.html
Lucene 中的Tokenizer, TokenFilter学习相关推荐
- 理解Lucene中的Analyzer
学习一个库,最好去官网.因为很多库API变动十分大,从博客上找的教程都过时了. Lucene原理就是简简单单的"索引",以空间换时间.但是Lucene将这件事做到了极致,后人再有想 ...
- Lucene中的同义词
Lucene中的同义词 Lucene的TokenFilter中,有SynonymFilter和SynonymGraphFilter两种来处理同义词. SynonymFilter不能很好的处理多词同义词 ...
- BERT中的Tokenizer说明
BERT中的Tokenizer说明 预训练BERT的Tokenizer有着强大的embedding的表征能力,基于BERT的Tokenizer的特征矩阵可以进行下游任务,包括文本分类,命名实体识别,关 ...
- CVPR2020:点云分析中三维图形卷积网络中可变形核的学习
CVPR2020:点云分析中三维图形卷积网络中可变形核的学习 Convolution in the Cloud: Learning Deformable Kernels in 3D Graph Con ...
- 读后感与机翻《从视频中推断力量和学习人类效用》
以下是研究朱松纯FPICU概念中U(utility)的相关论文记录: 读后感: 作者干了什么事? (1)算法能够预测当人们与物体交互时,身体各个部位(臀部.背部.头部.颈部.手臂.腿等)所承受的力/压 ...
- Blender中的主程序纹理学习课程 Master Procedural Texturing in Blender
挖掘Blender不可思议的强大节点编辑器的无限潜力. 你会学到: 逐步构建高级和高度可定制的程序纹理. 将许多不同层次的细节结合成一个复杂而现实的结果. 从头开始构建高级程序纹理背后的思维过程. 使 ...
- UE5虚幻引擎5中的实时特效学习 Introduction to real time FX in Unreal Engine 5
MP4 |视频:h264,1280×720 |音频:AAC,44.1 KHz,2 Ch 语言:英语+中英文字幕(根据原英文字幕机译更准确) |时长:40节课(3h 36m) |大小解压后:2.65 G ...
- MySQL中的联合索引学习教程
MySQL中的联合索引学习教程 这篇文章主要介绍了MySQL中的联合索引学习教程,其中谈到了联合索引对排序的优化等知识点,需要的朋友可以参考下 联合索引又叫复合索引.对于复合索引:Mysql从左到右的 ...
- python中字典和集合的区别_Python中字典和集合学习小结
映射类型: 表示一个任意对象的集合,且可以通过另一个几乎是任意键值的集合进行索引 与序列不同,映射是无序的,通过键进行索引 任何不可变对象都可用作字典的键,如字符串.数字.元组等 包含可变对象的列表. ...
最新文章
- openStack调试
- 从零开始React:一档 React环境搭建,语法规则,基础使用
- jquery中的each各种神奇遍历用法
- TensorFlow 2.0 - Keras Pipeline、自定义Layer、Loss、Metric
- 对谈|人工智能来了,翻译们会失业吗?
- 信息学奥赛C++语言:统计数字字符个数
- MYSQL DELETE 别名
- 求链表是否有环和第一个交点
- 静态成员变量以及静态成员函数
- mysql课件_MYSQL讲课时的PPT课件.ppt
- gohost -- go 开发的命令行hosts配置管理工具
- JS编程练习题(javascript)
- Java Caledar类(日历类)判断本周周数
- 毕业软件测试论文大纲,测试论文大纲模板范本 测试论文提纲怎样写
- HTML元素居中的方法
- 明哥,给大学生的几点建议
- 一次和前端的相互甩锅的问题记录
- Hololens2开机无法启动无法开机问题
- Android 播放视频
- 记录下在线扩容服务器遇到的问题 NOCHANGE: partition 1 is size 419428319. it cannot be grown
热门文章
- numpy随机生成01矩阵_NumPy数组基本介绍
- linux连接磁盘阵列,CentOS/Linux 连接 iSCSI 磁盘阵列
- matlab usewhitebg,我有一个matlab的程序运行出错,各位大神求救,很急啊
- python计算汽车的平均油耗_汽车行车电脑中的平均油耗是按哪个行驶里程计算的?...
- 13 登陆_13级!凌晨,“黑格比”登陆!对莆田的最新影响……
- oracle union详解,Oracle中的union和join
- 燃烧温度计算程序_【知识库】燃气燃烧器如何安全操作?
- html如何添加关闭按钮,大神你好,请问怎么在以下代码的div中添加一个关闭按钮?...
- 有没有测试水泥稳定性的软件,水泥稳定碎石土7天无侧限抗压强度制件(参考模板)...
- Android:相对布局综合小演练—智能家居,按键快速美化的小技巧