对于索引和查询,我需要执行下面列出的某些转换。因此我写了一个自定义过滤器。如何执行令牌的连接,并将其传递给NGramFilterFactory过滤器。请告诉我代码中需要改进的地方。
这是schema.xml文件中的配置:
<tokenizer class="solr.WhitespaceTokenizerFactory"/>
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.TrimFilterFactory" />
<filter class="solr.TrimFilterFactory" pattern="([^a-z])" replacement="" replace="all" />
<filter class="solr.StopFilterFactory" ignoreCase="true" words="custom_stop_words.txt"/>
<filter class="intuit.ripple.solr.ConcatFilterFactory" />
<filter class="solr.NGramFilterFactory" minGramSize="3" maxGramSize="3" />
以下是我要解决的用例示例:
1. Input value: "foo Bar Baz qux"
2. WhitespaceTokenizerFactory: "foo", "Bar", "Baz", "qux"
3. LowerCaseFilterFactory: "foo", "bar", "baz", "qux"
4. TrimFilterFactory, TrimFilterFactory and StopFilterFactory have nothing to do in this case.
5. ConcatFilterFactory: "foobarbazqux". It should concatenate the tokens.
6. NGramFilterFactory: This will generate the token.
以下是来自ConcatFilter的incrementToken()
方法:
@Override
public boolean incrementToken() throws IOException {
StringBuilder builder = new StringBuilder();
while (input.incrementToken()) {
int len = charTermAtt.length();
char buffer[] = charTermAtt.buffer();
builder.append(buffer, 0, len);
System.out.println("Tokens: " + new String(buffer, 0, len));
clearAttributes();
charTermAtt.setEmpty();
}
System.out.println("Concat tokens: " + builder.toString());
charTermAtt.copyBuffer(builder.toString().toCharArray(), 0, builder.length());
charTermAtt.setLength(builder.length());
posIncAtt.setPositionIncrement(1);
setOffsetAttr.setOffset(0, builder.length());
input.end();
input.close();
return false;
}
这里我使用while循环来获取所有令牌并将它们连接在一起。有没有办法在不循环的情况下一次获取所有令牌?
答案 0 :(得分:0)
我认为你想要做的事情比你实施的更多:D
您在incrementToken方法中所做的只是遍历整个输入(在本例中是StopFilter的输出)。在每次增量令牌调用中,您应该从输入中获取单个(或更多,如果需要)令牌,并生成SINGLE令牌以输出。
所以我猜你不想在这里使用“while”循环,而且在每次交互中调用“clearAttributes()”。
我猜也猜你这样:
Tokens: foo
Tokens: bar
Concat tokens: foo bar
但实际上从两个令牌“foo”和“bar”中你制作了单个令牌“foo bar”,我猜这不是你的意图。请描述您的ConcatFilterFactory应该做什么。目前,它只将多个令牌合并为单个令牌。
您在此处有一个关于TokenFilter的讨论示例:http://search-lucene.com/m/ukJmjphJte/tokenfilter&subj=custom+TokenFilter。您可以使用此搜索框查找有关Solr / Lucene相关信息的更多信息:http://search-lucene.com/
答案 1 :(得分:0)
我认为无法一次获取所有令牌,您需要像在代码中一样进行循环。但你可以使用不同的方法。而不是使用solr.WhitespaceTokenizerFactory
使用solr.KeywordTokenizerFactory
。 KeywordTokenizerFactory
只在令牌流中放入一个精确输入值的标记。然后在ConcatFilter
中,您只需从令牌流中获取第一个也是唯一的令牌,并将其中的所有空格替换为空字符串。在这种情况下,您需要在StopFilter
之后添加NGramFilter
。使用您的示例,您将拥有:
1. Input value: "foo Bar Baz qux"
2. KeywordTokenizerFactory: "foo Bar Baz qux"
3. LowerCaseFilterFactory: "foo bar baz qux"
4. ConcatFilterFactory: "foobarbazqux".
5. NGramFilterFactory: This will generate the token.
6. StopFilterFactory cuts all unwanted tokens.