Neo4j 3x 和旧版 node_auto_indexing 带有自定义 Lucene 分析器
Neo4j 3x and legacy node_auto_indexing with custom Lucene Analyzer
在我的 Neo4j 3.0.3 和 SDN 4.2 中。0.BUILD-SNAPSHOT 我创建了以下配置:
@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;
}
...
}
此外,我已经实施了 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);
}
...
}
现在我的测试失败了,因为看起来 StandardAnalyzerV36
没有正确应用于索引。
我做错了什么以及如何解决?
已更新
我正在尝试使用 ogm.properties
:
配置驱动程序
driver=org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver
dbms.auto_index.nodes.keys=name,description
dbms.auto_index.nodes.enabled=true
和配置:
@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");
}
}
但是还是不行。
应该在 ogm.properties
中放置什么设置?
我认为您不应该创建新的嵌入式驱动程序:Components.setDriver(new EmbeddedDriver(graphDatabaseService()));
相反,从已配置的驱动程序中获取 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();
}
如果您想以编程方式配置嵌入式驱动程序,那么您可以在 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> );
}
或者像这样只用 OGM:
Configuration configuration = new Configuration()
.driverConfiguration()
.setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver")
.setURI(uri);
然后使用与上面相同的方法获取底层图形数据库的句柄。
更新:
ogm.properties 不支持 dbms.auto_index.nodes.keys 或 dbms.auto_index.nodes.enabled。这些将在创建 GraphDatabaseService 时进行配置,当前版本的 OGM 无法执行此操作。参见 https://github.com/neo4j/neo4j-ogm/issues/134
在我的 Neo4j 3.0.3 和 SDN 4.2 中。0.BUILD-SNAPSHOT 我创建了以下配置:
@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;
}
...
}
此外,我已经实施了 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);
}
...
}
现在我的测试失败了,因为看起来 StandardAnalyzerV36
没有正确应用于索引。
我做错了什么以及如何解决?
已更新
我正在尝试使用 ogm.properties
:
driver=org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver
dbms.auto_index.nodes.keys=name,description
dbms.auto_index.nodes.enabled=true
和配置:
@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");
}
}
但是还是不行。
应该在 ogm.properties
中放置什么设置?
我认为您不应该创建新的嵌入式驱动程序:Components.setDriver(new EmbeddedDriver(graphDatabaseService()));
相反,从已配置的驱动程序中获取 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();
}
如果您想以编程方式配置嵌入式驱动程序,那么您可以在 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> );
}
或者像这样只用 OGM:
Configuration configuration = new Configuration()
.driverConfiguration()
.setDriverClassName("org.neo4j.ogm.drivers.embedded.driver.EmbeddedDriver")
.setURI(uri);
然后使用与上面相同的方法获取底层图形数据库的句柄。
更新: ogm.properties 不支持 dbms.auto_index.nodes.keys 或 dbms.auto_index.nodes.enabled。这些将在创建 GraphDatabaseService 时进行配置,当前版本的 OGM 无法执行此操作。参见 https://github.com/neo4j/neo4j-ogm/issues/134