|
Solr и собственный токенайзер
#38365684
Ссылка:
Ссылка на сообщение:
Ссылка с названием темы:
|
|
|
|
Добрый день!
Вот возникла проблема с собственным токенайзером для Solr. Мы разработали собственный токенайзер для Solr, чтобы он вычленял из текста номера телефонов и помещал возможные варианты как дополнительные токены. Но к сожалению эти дополнительные варианты номера телефона не индексируются Solr. Для примера приведу текст "Привет (111) 222-33-44 всем!" раскладывается нашим токенайзером в токены: "2223344", "1112223344", "71112223344", "81112223344", "привет", "111", "222", "33", "44", "всем". При этом поиск по токенам "2223344", "1112223344", "71112223344", "81112223344" не происходит. Подскажите в чем может быть дело. Мы используем Solr 4.3.1. Далее идут исходные тексты:
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90. 91. 92. 93. 94. 95. 96. 97. 98. 99. 100. 101. 102. 103. 104. 105. 106. 107. 108. 109. 110. 111. 112. 113. 114. 115. 116. 117. 118. 119. 120. 121. 122. 123. 124. 125. 126. 127. 128. 129. 130. 131. 132. 133. 134. 135. 136. 137. 138. 139. 140. 141. 142. 143. 144. 145. 146. 147. 148. 149. 150. 151. 152. 153. 154. 155. 156. 157. 158. 159. 160. 161. 162. 163. 164. 165. 166. 167. 168. 169. 170. 171. 172. 173. 174. 175. 176. 177. 178. 179. 180. 181. 182. 183. 184. 185. 186. 187. 188. 189. 190. 191. 192. 193. 194. 195. 196. 197. 198. 199. 200. 201. 202. 203. 204. 205. 206. 207.
public class HJStandardTokenizer extends Tokenizer{
private StandardTokenizerInterface scanner;
public static final int ALPHANUM = 0;
/** @deprecated (3.1) */
@Deprecated
public static final int APOSTROPHE = 1;
/** @deprecated (3.1) */
@Deprecated
public static final int ACRONYM = 2;
/** @deprecated (3.1) */
@Deprecated
public static final int COMPANY = 3;
public static final int EMAIL = 4;
/** @deprecated (3.1) */
@Deprecated
public static final int HOST = 5;
public static final int NUM = 6;
/** @deprecated (3.1) */
@Deprecated
public static final int CJ = 7;
/** @deprecated (3.1) */
@Deprecated
public static final int ACRONYM_DEP = 8;
public static final int SOUTHEAST_ASIAN = 9;
public static final int IDEOGRAPHIC = 10;
public static final int HIRAGANA = 11;
public static final int KATAKANA = 12;
public static final int HANGUL = 13;
/** String token types that correspond to token type int constants */
public static final String [] TOKEN_TYPES = new String [] {
"<ALPHANUM>",
"<APOSTROPHE>",
"<ACRONYM>",
"<COMPANY>",
"<EMAIL>",
"<HOST>",
"<NUM>",
"<CJ>",
"<ACRONYM_DEP>",
"<SOUTHEAST_ASIAN>",
"<IDEOGRAPHIC>",
"<HIRAGANA>",
"<KATAKANA>",
"<HANGUL>"
};
private int maxTokenLength = StandardAnalyzer.DEFAULT_MAX_TOKEN_LENGTH;
private static class PhoneTextPosition {
public int position;
public int length;
public LinkedList<String> variants = new LinkedList<String>();
private PhoneTextPosition(int position, int length, Collection<String> phoneVariants) {
this.position = position;
this.length = length;
this.variants.addAll(phoneVariants);
}
@Override
public int hashCode() {
return (new Integer(position).hashCode());
}
@Override
public boolean equals(Object obj) {
if (obj instanceof PhoneTextPosition) {
PhoneTextPosition otherObj = (PhoneTextPosition)obj;
if (position == otherObj.position &&
length == otherObj.length)
return true;
}
return false;
}
}
private LinkedList<PhoneTextPosition> phoneVariants;
/** Set the max allowed token length. Any token longer
* than this is skipped. */
public void setMaxTokenLength(int length) {
this.maxTokenLength = length;
}
/** @see #setMaxTokenLength */
public int getMaxTokenLength() {
return maxTokenLength;
}
/**
* Creates a new instance of the {@link org.apache.lucene.analysis.standard.StandardTokenizer}. Attaches
* the <code>input</code> to the newly created JFlex scanner.
*
* @param input The input reader
*
* See http://issues.apache.org/jira/browse/LUCENE-1068
*/
public HJStandardTokenizer(Version matchVersion, Reader input) {
super(input);
init(matchVersion);
}
/**
* Creates a new StandardTokenizer with a given {@link org.apache.lucene.util.AttributeSource.AttributeFactory}
*/
public HJStandardTokenizer(Version matchVersion, AttributeFactory factory, Reader input, Collection<HJPhoneNumber> phones) {
super(factory, input);
init(matchVersion);
phoneVariants = new LinkedList<PhoneTextPosition>();
for (HJPhoneNumber phone : phones) {
PhoneTextPosition position = new PhoneTextPosition(
phone.getPositionInText(),
phone.getLengthInText(),
phone.getAllVariants());
phoneVariants.add(position);
}
}
private final void init(Version matchVersion) {
this.scanner = new StandardTokenizerImpl(null);
}
// this tokenizer generates three attributes:
// term offset, positionIncrement and type
private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
private final OffsetAttribute offsetAtt = addAttribute(OffsetAttribute.class);
private final PositionIncrementAttribute posIncrAtt = addAttribute(PositionIncrementAttribute.class);
private final TypeAttribute typeAtt = addAttribute(TypeAttribute.class);
/*
* (non-Javadoc)
*
* @see org.apache.lucene.analysis.TokenStream#next()
*/
@Override
public final boolean incrementToken() throws IOException {
clearAttributes();
if (phoneVariants.size() > 0) {
PhoneTextPosition p = phoneVariants.peek();
try {
String variant = p.variants.poll();
if (StringUtils.isNotEmpty(variant)) {
posIncrAtt.setPositionIncrement(1);
char[] buf = variant.toCharArray();
termAtt.resizeBuffer(buf.length);
termAtt.copyBuffer(buf, 0, buf.length);
final int start = p.position;
offsetAtt.setOffset(correctOffset(start), correctOffset(start+p.length));
typeAtt.setType(HJStandardTokenizer.TOKEN_TYPES[HJStandardTokenizer.NUM]);
return true;
}
} finally {
if (p.variants.size() == 0) {
phoneVariants.remove(p);
}
}
}
int posIncr = 1;
while(true) {
int tokenType = scanner.getNextToken();
if (tokenType == StandardTokenizerInterface.YYEOF) {
return false;
}
if (scanner.yylength() <= maxTokenLength) {
posIncrAtt.setPositionIncrement(posIncr);
scanner.getText(termAtt);
final int start = scanner.yychar();
offsetAtt.setOffset(correctOffset(start), correctOffset(start+termAtt.length()));
// This 'if' should be removed in the next release. For now, it converts
// invalid acronyms to HOST. When removed, only the 'else' part should
// remain.
if (tokenType == HJStandardTokenizer.ACRONYM_DEP) {
typeAtt.setType(HJStandardTokenizer.TOKEN_TYPES[HJStandardTokenizer.HOST]);
termAtt.setLength(termAtt.length() - 1); // remove extra '.'
} else {
typeAtt.setType(HJStandardTokenizer.TOKEN_TYPES[tokenType]);
}
return true;
} else
// When we skip a too-long term, we still increment the
// position increment
posIncr++;
}
}
@Override
public final void end() {
// set final offset
int finalOffset = correctOffset(scanner.yychar() + scanner.yylength());
offsetAtt.setOffset(finalOffset, finalOffset);
}
@Override
public void reset() throws IOException {
scanner.yyreset(input);
}
}
1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30.
public class HJStandardTokenizerFactory extends TokenizerFactory{
private final int maxTokenLength;
public HJStandardTokenizerFactory(Map<String, String> args) {
super(args);
assureMatchVersion();
maxTokenLength = getInt(args, "maxTokenLength", StandardAnalyzer.DEFAULT_MAX_TOKEN_LENGTH);
if (!args.isEmpty()) {
throw new IllegalArgumentException("Unknown parameters: " + args);
}
}
@Override
public Tokenizer create(AttributeSource.AttributeFactory factory, Reader input) {
String content = null;
HJPhoneNumberHelper hjPhoneNumberHelper = null;
StringReader stringReader = null;
try {
content = IOUtils.toString(input);
hjPhoneNumberHelper = new HJPhoneNumberHelper(content);
stringReader = new StringReader(content);
} catch (IOException e) {
}
HJStandardTokenizer tokenizer = new HJStandardTokenizer(luceneMatchVersion, factory, stringReader,
hjPhoneNumberHelper.getPhoneNumbers());
tokenizer.setMaxTokenLength(maxTokenLength);
return tokenizer;
}
}
|
|
|