Может ли Cypher выполнять фонетический поиск текста только по части текста без использования эластичного поиска?
Скажем, у меня есть работа финансового администратора (j:Job {name: 'financial administrator'}).
Многие люди используют разные названия для «финансового администратора». Поэтому я хочу, чтобы вышеупомянутая работа была хитом, даже если люди вводят только «финансовый» или «администратор», а в их вводе есть опечатки (например: «финансовый»).
CONTAINS дает результаты только при 100% совпадении - так что без опечаток.
Большое спасибо!
2 ответа
Это заняло некоторое время, вот как я решил свой вопрос.
MATCH (a)-[:IS]->(hs)
UNWIND a.naam AS namelist
CALL apoc.text.phonetic(namelist) YIELD value
WITH value AS search_str, SPLIT('INPUT FROM DATABASE', ' ') AS input, a
CALL apoc.text.phonetic(input) YIELD value
WITH value AS match_str, search_str, a
WHERE search_str CONTAINS match_str OR search_str = match_str
RETURN DISTINCT a.naam, label(a)
Во-первых, вы можете попробовать нечеткое сопоставление с полнотекстовым индексом и посмотреть, решит ли это проблему. Примером может быть: Настройте индекс -
CALL db.index.fulltext.createNodeIndex('jobs', ['Job'], ['name'], {})
Запросить индекс с нечетким соответствием (обратите внимание на
~
)
CALL db.index.fulltext.queryNodes('jobs', 'fynancial~')
Если вы хотите пойти дальше и использовать фонетический поиск Lucene, вы можете написать небольшой код Java для регистрации пользовательского анализатора.
Включите
lucene-analyzers-phonetic
зависимость так:
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-phonetic</artifactId>
<version>8.5.1</version>
</dependency>
Затем создайте собственный анализатор:
@ServiceProvider
public class PhoneticAnalyzer extends AnalyzerProvider {
public PhoneticAnalyzer() {
super("phonetic");
}
@Override
public Analyzer createAnalyzer() {
return new Analyzer() {
@Override
protected TokenStreamComponents createComponents(String s) {
Tokenizer tokenizer = new StandardTokenizer();
TokenStream stream = new DoubleMetaphoneFilter(tokenizer, 6, true);
return new TokenStreamComponents(tokenizer, stream);
}
};
}
}
Я использовал DoubleMetaphoneFilter, но вы можете поэкспериментировать с другими. Упакуйте его как банку и поместите в каталог плагинов Neo4j вместе с фонетической банкой Lucene и перезапустите сервер. Затем с помощью этого анализатора создайте полнотекстовый индекс:
CALL db.index.fulltext.createNodeIndex('jobs', ['Job'], ['name'], {analyzer:'phonetic'})
Запрос индекса выглядит так же:
CALL db.index.fulltext.queryNodes('jobs', 'fynancial')