Может ли 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')

Другие вопросы по тегам