Lucene分词心得--使搜索转义字符(如'+')成为可能
来源:互联网 发布:美苹互联域名如何解析 编辑:程序博客网 时间:2024/06/06 19:54
想写BLOG,又不知道写些什么(只是最近刚想是不是该写个自已的BLOG)。于是乎,把以前曾经在项目中用到的一个东东写上了,个人愚见:).
使用LUCENE时,搜索'c++'这样的词会出现空的结果.原因肯定是在创建索引时出了问题,创建索引就需要分词,你没搜到'C++',就是因为没有c++这样一个分词加到索引中.
说完就开工,我仿照英文的分词方式,每个字母做一个分词,也就是'c++'被分成'c' '+' '+'三个,然后加在索引中.
这是最主要的分词,你可以自已设置想要参与分词的字符,放到你的Analyzer中使用吧.
顺便贴一下网上的ChineseAnalyzer,为了配合使用,改过后如下:
使用LUCENE时,搜索'c++'这样的词会出现空的结果.原因肯定是在创建索引时出了问题,创建索引就需要分词,你没搜到'C++',就是因为没有c++这样一个分词加到索引中.
说完就开工,我仿照英文的分词方式,每个字母做一个分词,也就是'c++'被分成'c' '+' '+'三个,然后加在索引中.
public sealed class ChineseTokenizer : Tokenizer
{
public ChineseTokenizer(TextReader _in)
{
input = _in;
}
private int offset = 0;//偏移量
private int bufferIndex = 0;////词汇在缓冲中的位置
private int dataLen = 0;//缓冲字符的长度
private static int MAX_WORD_LEN = 255;
private static int IO_BUFFER_SIZE = 1024;
private char[] buffer = new char[MAX_WORD_LEN];
private char[] ioBuffer = new char[IO_BUFFER_SIZE];
private int length;//词汇的长度
private int start;//开始偏移量.
private void Push(char c)
{
if (length == 0) start = offset - 1; // 分词起始位置
buffer[length++] = Char.ToLower(c); // 加入缓冲区
}
private Token Flush()
{
if (length > 0)
{
return new Token(new String(buffer, 0, length), start, start + length);
}
else
return null;
}
public override Token Next()
{
length = 0;
start = offset;
while (true)
{
char c;
offset++;
if (bufferIndex >= dataLen)
{
dataLen = input.Read(ioBuffer, 0, ioBuffer.Length);
bufferIndex = 0;
};
if (dataLen == 0) return Flush();
else
c = ioBuffer[bufferIndex++];
if (c == ','
|| c == ','
|| c == ';'
|| c == ';')//排除字符, ; ,;参与分词
{
if (length > 0) return Flush();
continue;
}
switch (Char.GetUnicodeCategory(c))
{
case UnicodeCategory.DecimalDigitNumber://指示字符是十进制数字;即在范围 0 到 9 内
case UnicodeCategory.LowercaseLetter://指示字符是小写字母
case UnicodeCategory.UppercaseLetter://指示字符是大写字母
Push(c);
if (length == MAX_WORD_LEN) return Flush();
break;
case UnicodeCategory.MathSymbol://指示字符是数学符号,例如“+”或“=”。
case UnicodeCategory.OpenPunctuation://指示字符是成对的标点符号(例如括号、方括号和大括号)之一的开始字符
case UnicodeCategory.ClosePunctuation://指示字符是成对的标点符号(例如括号、方括号和大括号)之一的封闭字符
case UnicodeCategory.CurrencySymbol://货币符号
case UnicodeCategory.DashPunctuation://指示字符是短划线或连字符
case UnicodeCategory.ModifierSymbol://指示字符是修饰符符号,这指示环绕的字符的修改 例如:^
case UnicodeCategory.OtherPunctuation://指示字符是标点,但它不是连接符标点、短划线标点、开始标点、结束标点、前引号标点或后引号标点,如:%
case UnicodeCategory.OtherLetter:
if (length > 0)
{
bufferIndex--;
offset--;
return Flush();
}
Push(c);
return Flush();
default:
if (length > 0)
{
return Flush();
}
break;
}
}
}
}
{
public ChineseTokenizer(TextReader _in)
{
input = _in;
}
private int offset = 0;//偏移量
private int bufferIndex = 0;////词汇在缓冲中的位置
private int dataLen = 0;//缓冲字符的长度
private static int MAX_WORD_LEN = 255;
private static int IO_BUFFER_SIZE = 1024;
private char[] buffer = new char[MAX_WORD_LEN];
private char[] ioBuffer = new char[IO_BUFFER_SIZE];
private int length;//词汇的长度
private int start;//开始偏移量.
private void Push(char c)
{
if (length == 0) start = offset - 1; // 分词起始位置
buffer[length++] = Char.ToLower(c); // 加入缓冲区
}
private Token Flush()
{
if (length > 0)
{
return new Token(new String(buffer, 0, length), start, start + length);
}
else
return null;
}
public override Token Next()
{
length = 0;
start = offset;
while (true)
{
char c;
offset++;
if (bufferIndex >= dataLen)
{
dataLen = input.Read(ioBuffer, 0, ioBuffer.Length);
bufferIndex = 0;
};
if (dataLen == 0) return Flush();
else
c = ioBuffer[bufferIndex++];
if (c == ','
|| c == ','
|| c == ';'
|| c == ';')//排除字符, ; ,;参与分词
{
if (length > 0) return Flush();
continue;
}
switch (Char.GetUnicodeCategory(c))
{
case UnicodeCategory.DecimalDigitNumber://指示字符是十进制数字;即在范围 0 到 9 内
case UnicodeCategory.LowercaseLetter://指示字符是小写字母
case UnicodeCategory.UppercaseLetter://指示字符是大写字母
Push(c);
if (length == MAX_WORD_LEN) return Flush();
break;
case UnicodeCategory.MathSymbol://指示字符是数学符号,例如“+”或“=”。
case UnicodeCategory.OpenPunctuation://指示字符是成对的标点符号(例如括号、方括号和大括号)之一的开始字符
case UnicodeCategory.ClosePunctuation://指示字符是成对的标点符号(例如括号、方括号和大括号)之一的封闭字符
case UnicodeCategory.CurrencySymbol://货币符号
case UnicodeCategory.DashPunctuation://指示字符是短划线或连字符
case UnicodeCategory.ModifierSymbol://指示字符是修饰符符号,这指示环绕的字符的修改 例如:^
case UnicodeCategory.OtherPunctuation://指示字符是标点,但它不是连接符标点、短划线标点、开始标点、结束标点、前引号标点或后引号标点,如:%
case UnicodeCategory.OtherLetter:
if (length > 0)
{
bufferIndex--;
offset--;
return Flush();
}
Push(c);
return Flush();
default:
if (length > 0)
{
return Flush();
}
break;
}
}
}
}
顺便贴一下网上的ChineseAnalyzer,为了配合使用,改过后如下:
public sealed class ChineseFilter : TokenFilter
{
public static String[] STOP_WORDS =
{
"and", "are", "as", "at", "be", "but", "by",
"for", "if", "in", "into", "is", "it",
"no", "not", "of", "on", "or", "such",
"that", "the", "their", "then", "there", "these",
"they", "this", "to", "was", "will", "with"
};
private Hashtable stopTable;
public ChineseFilter(TokenStream _in) : base (_in)
{
stopTable = new Hashtable(STOP_WORDS.Length);
for (int i = 0; i < STOP_WORDS.Length; i++)
stopTable[STOP_WORDS[i]] = STOP_WORDS[i];
}
public override Token Next()
{
for (Token token = input.Next(); token != null; token = input.Next())
{
String text = token.TermText();
if (stopTable[text] == null)
{
return token;
}
}
return null;
}
}
public class ChineseAnalyzer : Analyzer
{
public ChineseAnalyzer()
{
}
public override sealed TokenStream TokenStream(String fieldName, TextReader reader)
{
TokenStream result = new ChineseTokenizer(reader);
result = new ChineseFilter(result);
return result;
}
}
{
public static String[] STOP_WORDS =
{
"and", "are", "as", "at", "be", "but", "by",
"for", "if", "in", "into", "is", "it",
"no", "not", "of", "on", "or", "such",
"that", "the", "their", "then", "there", "these",
"they", "this", "to", "was", "will", "with"
};
private Hashtable stopTable;
public ChineseFilter(TokenStream _in) : base (_in)
{
stopTable = new Hashtable(STOP_WORDS.Length);
for (int i = 0; i < STOP_WORDS.Length; i++)
stopTable[STOP_WORDS[i]] = STOP_WORDS[i];
}
public override Token Next()
{
for (Token token = input.Next(); token != null; token = input.Next())
{
String text = token.TermText();
if (stopTable[text] == null)
{
return token;
}
}
return null;
}
}
public class ChineseAnalyzer : Analyzer
{
public ChineseAnalyzer()
{
}
public override sealed TokenStream TokenStream(String fieldName, TextReader reader)
{
TokenStream result = new ChineseTokenizer(reader);
result = new ChineseFilter(result);
return result;
}
}
- Lucene分词心得--使搜索转义字符(如'+')成为可能
- Lucene 高亮 分词 搜索
- xml 转义特殊字符 如&'"
- xml 转义特殊字符 如&'"
- xml 转义特殊字符 如&'"
- lucene的建立索引,搜索,中文分词
- Lucene用标准分词器搜索索引
- [XML]xml 转义特殊字符 如&'"
- 新趋势:让基因搜索成为可能
- lucene分词
- lucene分词
- Lucene 分词
- Lucene分词器(搜索关键字解析器)
- Lucene学习笔记(二)——搜索,分词
- lucene分词器分词
- Lucene全文搜索之分词器:使用IK Analyzer中文分词器(修改IK Analyzer源码使其支持lucene5.5.x)
- java之全文索引搜索lucene之增删改查文档与中文分词搜索
- lucene分词器分词demo
- java关于(io&nio) 的 文件copy例子
- sql server 2005 T-SQL CASE (Transact-SQL)
- sql server 2005 T-SQL CAST 和 CONVERT (Transact-SQL)
- 人生是一只兔子(图)
- sql server 2005 T-SQL CEILING (Transact-SQL)
- Lucene分词心得--使搜索转义字符(如'+')成为可能
- wtc部署问题 多客户端连接tuxedo?
- 日期(datetime)的模糊查询
- solaris常用系统管理命令(2)
- ARCGIS DESKTOP 9.2 安装步骤
- 关于识别相似图像的算法探讨
- php导出CSV方法
- TUXEDO配置参数详解
- swfloader 的 SecurityError: Error #2122: Security sandbox violation