我有一个用例,我必须检查我收到的文本是否包含我拥有的300万个字符串中的任何一个。
我尝试了正则表达式匹配,但是一旦字符串列表越过50k,性能就越差
我正在为搜索列表中的每个单词执行此操作
inText = java.util.regex.Pattern.compile("\\b" + findStr + "\\b",
java.util.regex.Pattern.CASE_INSENSITIVE).matcher(intext).replaceAll(repl);
我知道我们可以使用像lucene这样的搜索索引,但我觉得那些主要用于从预定义文本中搜索特定文本,但我的用例是相反的,我需要发送一个大文本并检查是否有任何前文本中有定义的字符串
答案 0 :(得分:1)
我想,你可以采取相反的方式。您的预定义字符串是存储在倒排索引中的文档,您的传入文本是一个查询,您将根据文档进行测试。由于预定义的字符串不会发生太大变化,因此性能非常高。
我准备了一些Elasticsearch代码,可以解决问题。
public void add(String string, String id) {
IndexRequest indexRequest = new IndexRequest(INDEX, TYPE, id);
indexRequest.source(string);
index(INDEX, TYPE, id, string);
}
@Test
public void scoring() throws Exception {
// adding your predefined strings
add("{\"str\":\"string1\"}", "1");
add("{\"str\":\"alice\"}", "2");
add("{\"str\":\"bob\"}", "3");
add("{\"str\":\"string2\"}", "4");
add("{\"str\":\"melanie\"}", "5");
add("{\"str\":\"moana\"}", "6");
refresh(); // otherwise we would not anything
indexExists(INDEX); // verifies that index exists
ensureGreen(INDEX); // ensures cluster status is green
// querying your text separated by space, if the hits length is bigger than 0, you're good
SearchResponse searchResponse = client().prepareSearch(INDEX).setQuery(QueryBuilders.termsQuery("str", "string1", "string3", "melani")).execute().actionGet();
SearchHit[] hits = searchResponse.getHits().getHits();
assertThat(hits.length, equalTo(1));
for (SearchHit hit: hits) {
System.out.println(hit.getSource());
}
}