alexanoid
alexanoid

Reputation: 25852

Neo4j 3x and legacy node_auto_indexing with custom Lucene Analyzer

In my Neo4j 3.0.3 and SDN 4.2.0.BUILD-SNAPSHOT I have created a following configuration:

@Configuration
@EnableNeo4jRepositories(basePackages = "com.example")
@EnableTransactionManagement
public class Neo4jTestConfig extends Neo4jConfiguration {

    private static final String NEO4J_EMBEDDED_DATABASE_PATH_PROPERTY = "neo4j.embedded.database.path";

    @PostConstruct
    public void init() {
        Components.setDriver(new EmbeddedDriver(graphDatabaseService()));

        EmbeddedDriver embeddedDriver = (EmbeddedDriver) Components.driver();
        GraphDatabaseService databaseService = embeddedDriver.getGraphDatabaseService();
        try (Transaction t = databaseService.beginTx()) {
            Index<Node> autoIndex = databaseService.index().forNodes("node_auto_index");
            databaseService.index().setConfiguration(autoIndex, "type", "fulltext");
            databaseService.index().setConfiguration(autoIndex, "to_lower_case", "true");
            databaseService.index().setConfiguration(autoIndex, "analyzer", StandardAnalyzerV36.class.getName());
            t.success();
        }
    }

    public GraphDatabaseService graphDatabaseService() {

        // @formatter:off
        GraphDatabaseService graphDatabaseService = new GraphDatabaseFactory()
                .newEmbeddedDatabaseBuilder(new File(environment.getProperty(NEO4J_EMBEDDED_DATABASE_PATH_PROPERTY)))       
                .setConfig(GraphDatabaseSettings.node_keys_indexable, "name,description")
                .setConfig(GraphDatabaseSettings.node_auto_indexing, "true").
                newGraphDatabase();         
        // @formatter:on        

        return graphDatabaseService;
    }

...

}

Also, I have implemented StandardAnalyzerV36:

public final class StandardAnalyzerV36 extends Analyzer {

    public static final CharArraySet STOP_WORDS_SET = StopAnalyzer.ENGLISH_STOP_WORDS_SET;  

    @Override
    protected TokenStreamComponents createComponents(String fieldName) {

        final ClassicTokenizer src = new ClassicTokenizer();
        TokenStream tok = new StandardFilter(src);
        tok = new StopFilter(new LowerCaseFilter(tok), STOP_WORDS_SET);

        return new TokenStreamComponents(src, tok);
    }

    @Override
    protected Reader initReader(String fieldName, Reader reader) {
        return new HTMLStripCharFilter(reader);
    }   
...
}

Right now my test fails because of looks like StandardAnalyzerV36 is not correctly applied to index.

What am I doing wrong and how to fix it ?

UPDATED

I'm trying to configure driver with ogm.properties:

driver=org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver

dbms.auto_index.nodes.keys=name,description
dbms.auto_index.nodes.enabled=true

and config:

@Configuration
@EnableNeo4jRepositories(basePackages = "com.example")
@EnableTransactionManagement
public class Neo4jTestConfig extends Neo4jConfiguration {

    @Resource
    private Environment environment;

    @PostConstruct
    public void init() {
        EmbeddedDriver embeddedDriver = (EmbeddedDriver) Components.driver();
        GraphDatabaseService databaseService = embeddedDriver.getGraphDatabaseService();

        try (Transaction t = databaseService.beginTx()) {
            Index<Node> autoIndex = databaseService.index().forNodes("node_auto_index");
            databaseService.index().setConfiguration(autoIndex, "type", "fulltext");
            databaseService.index().setConfiguration(autoIndex, "to_lower_case", "true");
            databaseService.index().setConfiguration(autoIndex, "analyzer", StandardAnalyzerV36.class.getName());
            t.success();
        }
    }

    @Override
    public SessionFactory getSessionFactory() {
        return new SessionFactory("com.example");
    }

}

but it still doesn't work.

What settings should be placed in ogm.properties ?

Upvotes: 1

Views: 423

Answers (1)

Luanne
Luanne

Reputation: 19373

I don't think you should create a new embedded driver: Components.setDriver(new EmbeddedDriver(graphDatabaseService()));

Instead, get the GraphDatabaseService from the already configured driver and use that?

     EmbeddedDriver embeddedDriver = (EmbeddedDriver) Components.driver();
     GraphDatabaseService databaseService = embeddedDriver.getGraphDatabaseService();
     try (Transaction t = databaseService.beginTx()) {
      Index<Node> autoIndex = databaseService.index().forNodes("node_auto_index");
      databaseService.index().setConfiguration(autoIndex, "type", "fulltext");
      databaseService.index().setConfiguration(autoIndex, "to_lower_case", "true");
      databaseService.index().setConfiguration(autoIndex, "analyzer", StandardAnalyzerV36.class.getName());
      t.success();
     }

If you want to configure the embedded driver programatically, then you can set it up like this in SDN

@Bean
public Configuration getConfiguration() {
   Configuration config = new Configuration();
   config
       .driverConfiguration()
       .setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver")
       .setURI("file:///var/tmp/graph.db");
   return config;
}

@Bean
public SessionFactory getSessionFactory() {
    return new SessionFactory(getConfiguration(), <packages> );
}

or like this with only the OGM:

Configuration configuration = new Configuration()
             .driverConfiguration()
             .setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver")
             .setURI(uri);

Then use the same method above to get a handle to the underlying graph database.

Update: ogm.properties does not support dbms.auto_index.nodes.keys or dbms.auto_index.nodes.enabled. These are to be configured when creating the GraphDatabaseService, there is no way to do this with the current version of the OGM. See https://github.com/neo4j/neo4j-ogm/issues/134

Upvotes: 2

Related Questions