我正在使用solr字符串字段来提供文本字段的精确匹配(我查看了文本字段类型并且不相信它对我有用 - 我想要完全重现Sql的LIKE功能,包括空格和通配符)。
我的问题是当我索引大文本字段时,Solr在搜索这些字段时不会返回任何数据。限制似乎是int16.max。
作为测试,我创建了一个包含id
字段和string
字段的索引。如果id
字段为“1”且string
字段包含40,000个字符:
id:1
将返回两个字段,其中包含40,000个字符,表明它已被编入索引。string:*
不会返回任何结果如果字符串字段只包含30,000个字符,则一切似乎都能正常工作。
我找不到任何说明这是限制的文档,也无法找到任何方法,因为4.0中删除了maxFieldLength而字符串字段不支持分析器。
是否有其他人遇到此问题或找到了解决方法?
答案 0 :(得分:2)
我花了很多时间在这上面,所以我发布了我提出的解决方案,以防其他人遇到这个问题。使用带有KeywordTokenizer的文本字段类型确实像字符串字段一样工作,直到我遇到的字符串字段类型的长度限制。
最终,我在阅读this thread之后创建了一个自定义标记器,并进行了一些更改:
他想要标准行为,所以他基于StandardTokenizer,而我希望它像字符串字段一样。我第一次尝试使用KeywordTokenizer,但仍然遇到了限制,所以最终我将我的基于WhitespaceTokenizer(下面更多)。
此处的代码已过期,无法与Solr 4.0配合使用。
WhitespaceTokenizer的代码非常短,它包含一个名为isTokenChar
的方法,返回!Character.isWhitespace(c);
。我只是将其改为总是返回true。之后我创建了一个TokenizerFactory来返回它并在schema.xml中以与链接线程相同的方式引用它。
MyCustomTokenizer.java:
package custom.analysis;
import java.io.Reader;
import org.apache.lucene.analysis.Tokenizer;
import org.apache.lucene.analysis.util.CharTokenizer;
import org.apache.lucene.util.AttributeSource;
import org.apache.lucene.util.Version;
public final class MyCustomTokenizer extends CharTokenizer {
public MyCustomTokenizer(Version matchVersion, Reader in) {
super(matchVersion, in);
}
public MyCustomTokenizer(Version matchVersion, AttributeSource source, Reader in) {
super(matchVersion, source, in);
}
public MyCustomTokenizer(Version matchVersion, AttributeFactory factory, Reader in) {
super(matchVersion, factory, in);
}
@Override
protected boolean isTokenChar(int c) {
return true; //!Character.isWhitespace(c);
}
}
MyCustomTokenizerFactory.java:
package custom.analysis;
import org.apache.lucene.analysis.util.TokenizerFactory;
import org.apache.lucene.analysis.core.KeywordTokenizerFactory;
import org.apache.lucene.analysis.core.KeywordTokenizer;
import java.io.Reader;
import org.apache.lucene.util.Version;
public class MyCustomTokenizerFactory extends TokenizerFactory {
public MyCustomTokenizer create(Reader input) {
final MyCustomTokenizer tokenizer = new MyCustomTokenizer(Version.LUCENE_40, input);
return tokenizer;
}
}
schema.xml中:
<fieldType name="text_block" class="solr.TextField" positionIncrementGap="100">
<analyzer>
<tokenizer class="custom.analysis.MyCustomTokenizerFactory" />
</analyzer>
</fieldType>
使用这种方法,我能够使用字符串字段等功能索引大型文本字段(> 100k字符)。如果有人找到更好的方法,请发布!