我可以在Apache Solr中将String中的Field值获取到自定义TokenFilter中吗



我需要编写一个自定义的LemmaTokenFilter,它用它们的变元(基本(形式替换和索引单词。问题是,我从外部API获得基本形式,这意味着我需要调用API,发送文本,解析响应,并将其作为Map<String, String>发送到我的LemmaTokenFilter。映射包含成对的<originalWord, baseFormOfWord>。然而,我不知道如何访问TokenFilters正在处理的文本字段的全部值。

一个想法是,当LemmaTokenFilterFactory创建LemmaToken Filter时,一个接一个地遍历tokenStream,但我需要注意不要编辑tokenStream中的任何内容,以某种方式重置当前令牌(因为我需要调用其上的.increment()方法来获取所有令牌(,但最重要的是,这似乎没有必要,因为字段值已经在某个地方了,我不想花时间试图从令牌中重新组合它。这种实施可能太慢了。

另一个想法是单独处理每个令牌,但是只使用一个单词调用外部API,然后解析响应肯定效率太低了。

我发现了一些关于使用ResourceLoaderAware接口的东西,但我真的不明白如何利用它来达到我的优势。我可能可以在每次索引之前将地图保存在文本文件中,但在每次文档索引之前写入文件、打开文件并从中读取似乎也太慢了。

因此,最好的方法是将字段的值作为String传递给LemmaTokenFilter的构造函数,但我不知道如何从LemmaToken FilterFactory的create()方法访问它。

我在谷歌上找不到任何帮助,所以任何想法都是受欢迎的。

到目前为止,我拥有的是:

public final class LemmaTokenFilter extends TokenFilter {
private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
private Map<String, String> lemmaMap;
protected LemmaTokenFilter(TokenStream input, Map<String, String> lemmaMap) {
super(input);
this.lemmaMap = lemmaMap;
}
@Override
public boolean incrementToken() throws IOException {
if (input.incrementToken()) {
String term = termAtt.toString();
String lemma;
if ((lemma = lemmaMap.get(term)) != null) {
termAtt.setEmpty();
termAtt.copyBuffer(lemma.toCharArray(), 0, lemma.length());
}
return true;
} else {
return false;
}
}
}
public class LemmaTokenFilterFactory extends TokenFilterFactory implements ResourceLoaderAware {
public LemmaTokenFilterFactory(Map<String, String> args) {
super(args);
if (!args.isEmpty()) {
throw new IllegalArgumentException("Unknown parameters: " + args);
}
}
@Override
public TokenStream create(TokenStream input) {
return new LemmaTokenFilter(input, getLemmaMap(getFieldValue(input)));
}
private String getFieldValue(TokenStream input) {
//TODO: how?
return "Šach je desková hra pro dva hráče, v dnešní soutěžní podobě zároveň považovaná i za odvětví sportu.";
}
private Map<String, String> getLemmaMap(String data) {
return UdPipeService.getLemma(data);
}
@Override
public void inform(ResourceLoader loader) throws IOException {
}
}

1。基于API的方法: 您可以创建一个分析链,并在顶部使用自定义lemmatizer。要设计这个lemmatizer,我想你可以看看Keyword Tokenizer的实现;这样你就可以读取输入中的所有内容,然后调用你的API;替换输入文本中API响应中的所有令牌;之后,在分析链中,使用标准或空白标记器来标记您的数据。

2.基于文件的方法 它将遵循所有相同的步骤,除了调用API,它可以使用哈希图,从定义TokenStream时提到的文件中使用

现在使用ResourceLoaderAware:当您需要指示您的Tokenstream资源已更改时,需要使用inform方法进行处理。作为参考,您可以查看StemmerOverrideFilter

  • 关键字标记器:将整个输入作为单个标记发出

所以我想我找到了答案,或者实际上是两个答案。

一种方法是编写我的客户端应用程序,首先处理传入的请求-将字段值发送到外部API,并将响应存储到某个全局变量中,然后可以从自定义TokenFilters访问该全局变量。

另一种方法是使用自定义UpdateRequestProcessors,它允许我们修改传入文档的内容,调用外部API并再次保存响应,以便从自定义TokenFilters以某种方式全局访问它。在这里Erik Hatcher谈到了ScriptUpdateProcessor的使用,我相信它也可以用于我的情况。

希望这能帮助任何遇到类似问题的人,因为我很难找到解决方案(在SO上找不到任何类似的线程(

最新更新