neo4jfulltext-index

Multi-level full-text search in Neo4j


When I call db.index.fulltext.queryNodes() on an index, can I run another full-text query on the result? I need to search my database on 7-8 different properties across different Labels with different search parameters for each property. How do I go about it? If I use the reduce() function or apoc.coll.intersection and try to get an intersection, like...

CALL db.index.fulltext.queryNodes("first_name", "manas~") 
YIELD node as first_names
WITH collect(first_names) as first_name_list
CALL db.index.fulltext.queryNodes("aliases", "boncha~") 
YIELD node as aliases
WITH collect(aliases) as alias_list,first_name_list
RETURN apoc.coll.intersection(first_name_list, alias_list) AS output
LIMIT 5

wouldn’t that cause memory bloat?


Solution

  • You best use subqueries if using Neo4j 4.1+ :

    CALL {
        CALL db.index.fulltext.queryNodes("first_name", "manas~") 
        YIELD node, score
        RETURN node, score
    
        UNION ALL
        CALL db.index.fulltext.queryNodes("aliases", "boncha~") 
        YIELD node, score
        RETURN node, score
    }
    RETURN node, sum(score) AS totalScore
    ORDER BY totalScore DESC
    

    For the intersection, you can count per node how many matches they have, so if they have been matched in the two queries, it will be a count of two :

    CALL {
        CALL db.index.fulltext.queryNodes("first_name", "manas~") 
        YIELD node, score
        RETURN node, score
    
        UNION ALL
        CALL db.index.fulltext.queryNodes("aliases", "boncha~") 
        YIELD node, score
        RETURN node, score
    }
    WITH node, count(*) AS matches, sum(score) AS totalScore
    WITH node, matches, totalScore
    WHERE matches = 2
    ORDER BY totalScore DESC
    RETURN node, totalScore