DATAGRAPH-523 - Disable REST Schema Upload (GH #215)
This commit is contained in:
@@ -44,7 +44,7 @@
|
||||
|
||||
|
||||
<bean id="conversionService" class="org.springframework.data.neo4j.fieldaccess.Neo4jConversionServiceFactoryBean"/>
|
||||
<bean id="indexCreationMappingEventListener" class="org.springframework.data.neo4j.support.mapping.EntityIndexCreator">
|
||||
<bean id="indexCreationMappingEventListener" class="org.springframework.data.neo4j.support.mapping.DefaultEntityIndexCreator">
|
||||
<constructor-arg ref="indexProvider" />
|
||||
<constructor-arg ref="schemaIndexProvider" />
|
||||
</bean>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<context:annotation-config/>
|
||||
<neo4j:config graphDatabaseService="graphDatabaseService" />
|
||||
|
||||
<bean id="indexCreationMappingEventListener" class="org.springframework.data.neo4j.support.mapping.EntityIndexCreator">
|
||||
<bean id="indexCreationMappingEventListener" class="org.springframework.data.neo4j.support.mapping.DefaultEntityIndexCreator">
|
||||
<constructor-arg ref="indexProvider" />
|
||||
<constructor-arg ref="schemaIndexProvider" />
|
||||
</bean>
|
||||
@@ -67,4 +67,4 @@
|
||||
</bean>
|
||||
</beans>
|
||||
|
||||
</beans>
|
||||
</beans>
|
||||
|
||||
@@ -33,6 +33,7 @@ public class DataGraphBeanDefinitionParser extends AbstractBeanDefinitionParser
|
||||
|
||||
private static final String GRAPH_DATABASE_SERVICE = "graphDatabaseService";
|
||||
private static final String BASE_PACKAGE = "base-package";
|
||||
private static final String CREATE_INDEX = "create-index";
|
||||
public static final String ASPECTJ_CONFIG = "org.springframework.data.neo4j.aspects.config.Neo4jAspectConfiguration";
|
||||
public static final String CROSS_STORE_CONFIG = "org.springframework.data.neo4j.cross_store.config.CrossStoreNeo4jConfiguration";
|
||||
|
||||
@@ -43,10 +44,17 @@ public class DataGraphBeanDefinitionParser extends AbstractBeanDefinitionParser
|
||||
setupGraphDatabase(element, context, configBuilder);
|
||||
setupEntityManagerFactory(element, configBuilder);
|
||||
setupBaseEntities(element, configBuilder);
|
||||
setUpIndexCreation(element, configBuilder);
|
||||
setupConfigurationClassPostProcessor(context);
|
||||
return getSourcedBeanDefinition(configBuilder, element, context);
|
||||
}
|
||||
|
||||
private void setUpIndexCreation(Element element, BeanDefinitionBuilder configBuilder) {
|
||||
String createIndexAttribute = element.getAttribute(CREATE_INDEX);
|
||||
boolean createIndex = createIndexAttribute==null || !createIndexAttribute.equalsIgnoreCase("false");
|
||||
configBuilder.addPropertyValue("createIndex", createIndex);
|
||||
}
|
||||
|
||||
private void setupBaseEntities(Element element, BeanDefinitionBuilder configBuilder) {
|
||||
Set<String> initialEntityClasses = getInitialEntityClasses(element);
|
||||
if (initialEntityClasses!=null) {
|
||||
|
||||
@@ -51,7 +51,6 @@ import org.springframework.data.neo4j.support.typerepresentation.TypeRepresentat
|
||||
import org.springframework.data.neo4j.support.typesafety.TypeSafetyPolicy;
|
||||
import org.springframework.data.support.IsNewStrategyFactory;
|
||||
import org.springframework.transaction.PlatformTransactionManager;
|
||||
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
|
||||
|
||||
import javax.validation.Validator;
|
||||
|
||||
@@ -74,6 +73,7 @@ public abstract class Neo4jConfiguration { // implements TransactionManagementCo
|
||||
private ConversionService conversionService;
|
||||
|
||||
private Set<? extends Class<?>> initialEntitySet;
|
||||
private boolean createIndex = true;
|
||||
|
||||
@Autowired(required = false)
|
||||
private Validator validator;
|
||||
@@ -250,11 +250,12 @@ public abstract class Neo4jConfiguration { // implements TransactionManagementCo
|
||||
|
||||
@Bean
|
||||
public EntityIndexCreator entityIndexCreator() throws Exception {
|
||||
return new EntityIndexCreator(
|
||||
indexProvider(),
|
||||
schemaIndexProvider(),
|
||||
nodeTypeRepresentationStrategy().isLabelBased()
|
||||
);
|
||||
if (!createIndex) return new NoEntityIndexCreator();
|
||||
|
||||
return new DefaultEntityIndexCreator(
|
||||
indexProvider(),
|
||||
schemaIndexProvider(),
|
||||
nodeTypeRepresentationStrategy().isLabelBased());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -299,6 +300,14 @@ public abstract class Neo4jConfiguration { // implements TransactionManagementCo
|
||||
this.initialEntitySet = initialEntitySet;
|
||||
}
|
||||
|
||||
public void setCreateIndex(boolean createIndex) {
|
||||
this.createIndex = createIndex;
|
||||
}
|
||||
|
||||
public boolean isCreateIndex() {
|
||||
return createIndex;
|
||||
}
|
||||
|
||||
private String[] basePackage;
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/**
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.neo4j.support.mapping;
|
||||
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
|
||||
import org.springframework.data.neo4j.support.index.IndexProvider;
|
||||
import org.springframework.data.neo4j.support.index.IndexType;
|
||||
import org.springframework.data.neo4j.support.schema.SchemaIndexProvider;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 12.04.12
|
||||
*/
|
||||
public class DefaultEntityIndexCreator implements EntityIndexCreator {
|
||||
private IndexProvider indexProvider;
|
||||
private SchemaIndexProvider schemaIndexProvider;
|
||||
private boolean labelBased = true;
|
||||
|
||||
public DefaultEntityIndexCreator(IndexProvider indexProvider, SchemaIndexProvider schemaIndexProvider) {
|
||||
this(indexProvider, schemaIndexProvider,true);
|
||||
}
|
||||
public DefaultEntityIndexCreator(IndexProvider indexProvider, SchemaIndexProvider schemaIndexProvider, boolean labelBased) {
|
||||
this.indexProvider = indexProvider;
|
||||
this.schemaIndexProvider = schemaIndexProvider;
|
||||
this.labelBased = labelBased;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ensureEntityIndexes(Neo4jPersistentEntity<?> entity) {
|
||||
final Class entityType = entity.getType();
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<Neo4jPersistentProperty>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(Neo4jPersistentProperty property) {
|
||||
if (property.isIndexed() && property.getIndexInfo().isLabelBased()) {
|
||||
schemaIndexProvider.createIndex(property);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Pass 2 - do everything else
|
||||
if (!labelBased) indexProvider.getIndex(entity, null, IndexType.SIMPLE);
|
||||
entity.doWithProperties(new PropertyHandler<Neo4jPersistentProperty>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(Neo4jPersistentProperty property) {
|
||||
if (property.isIndexed() && !property.getIndexInfo().isLabelBased()){
|
||||
indexProvider.getIndex(property, entityType);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,66 +1,11 @@
|
||||
/**
|
||||
* Copyright 2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.neo4j.support.mapping;
|
||||
|
||||
import org.springframework.data.mapping.PropertyHandler;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentProperty;
|
||||
import org.springframework.data.neo4j.support.index.IndexProvider;
|
||||
import org.springframework.data.neo4j.support.index.IndexType;
|
||||
import org.springframework.data.neo4j.support.schema.SchemaIndexProvider;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 12.04.12
|
||||
* @since 19.10.14
|
||||
*/
|
||||
public class EntityIndexCreator {
|
||||
private IndexProvider indexProvider;
|
||||
private SchemaIndexProvider schemaIndexProvider;
|
||||
private boolean labelBased = true;
|
||||
|
||||
public EntityIndexCreator(IndexProvider indexProvider, SchemaIndexProvider schemaIndexProvider) {
|
||||
this(indexProvider, schemaIndexProvider,true);
|
||||
}
|
||||
public EntityIndexCreator(IndexProvider indexProvider, SchemaIndexProvider schemaIndexProvider, boolean labelBased) {
|
||||
this.indexProvider = indexProvider;
|
||||
this.schemaIndexProvider = schemaIndexProvider;
|
||||
this.labelBased = labelBased;
|
||||
}
|
||||
|
||||
public void ensureEntityIndexes(Neo4jPersistentEntity<?> entity) {
|
||||
final Class entityType = entity.getType();
|
||||
|
||||
entity.doWithProperties(new PropertyHandler<Neo4jPersistentProperty>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(Neo4jPersistentProperty property) {
|
||||
if (property.isIndexed() && property.getIndexInfo().isLabelBased()) {
|
||||
schemaIndexProvider.createIndex(property);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Pass 2 - do everything else
|
||||
if (!labelBased) indexProvider.getIndex(entity, null, IndexType.SIMPLE);
|
||||
entity.doWithProperties(new PropertyHandler<Neo4jPersistentProperty>() {
|
||||
@Override
|
||||
public void doWithPersistentProperty(Neo4jPersistentProperty property) {
|
||||
if (property.isIndexed() && !property.getIndexInfo().isLabelBased()){
|
||||
indexProvider.getIndex(property, entityType);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
public interface EntityIndexCreator {
|
||||
void ensureEntityIndexes(Neo4jPersistentEntity<?> entity);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import org.neo4j.graphdb.Relationship;
|
||||
import org.neo4j.index.lucene.ValueContext;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.data.annotation.Reference;
|
||||
import org.springframework.data.mapping.context.AbstractMappingContext;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
import org.springframework.data.mapping.model.MappingException;
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
package org.springframework.data.neo4j.support.mapping;
|
||||
|
||||
import org.springframework.data.neo4j.mapping.Neo4jPersistentEntity;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 19.10.14
|
||||
*/
|
||||
public class NoEntityIndexCreator implements EntityIndexCreator {
|
||||
@Override
|
||||
public void ensureEntityIndexes(Neo4jPersistentEntity<?> entity) {
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
http\://www.springframework.org/schema/data/neo4j/spring-neo4j-2.0.xsd=org/springframework/data/neo4j/config/spring-neo4j-2.0.xsd
|
||||
http\://www.springframework.org/schema/data/neo4j/spring-neo4j-2.1.xsd=org/springframework/data/neo4j/config/spring-neo4j-2.1.xsd
|
||||
http\://www.springframework.org/schema/data/neo4j/spring-neo4j-2.2.xsd=org/springframework/data/neo4j/config/spring-neo4j-2.2.xsd
|
||||
http\://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd=org/springframework/data/neo4j/config/spring-neo4j-2.2.xsd
|
||||
http\://www.springframework.org/schema/data/neo4j/spring-neo4j-3.0.xsd=org/springframework/data/neo4j/config/spring-neo4j-3.0.xsd
|
||||
http\://www.springframework.org/schema/data/neo4j/spring-neo4j-3.3.xsd=org/springframework/data/neo4j/config/spring-neo4j-3.3.xsd
|
||||
http\://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd=org/springframework/data/neo4j/config/spring-neo4j-3.3.xsd
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xsd:schema xmlns="http://www.springframework.org/schema/data/neo4j"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:repository="http://www.springframework.org/schema/data/repository"
|
||||
xmlns:tool="http://www.springframework.org/schema/tool"
|
||||
|
||||
targetNamespace="http://www.springframework.org/schema/data/neo4j"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.org/schema/tool"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/beans"/>
|
||||
<xsd:import namespace="http://www.springframework.org/schema/data/repository"
|
||||
schemaLocation="http://www.springframework.org/schema/data/repository/spring-repository.xsd"/>
|
||||
|
||||
<xsd:element name="config">
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="beans:identifiedType">
|
||||
<xsd:attribute name="storeDirectory" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
default store-directory of the Neo4j database
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
<xsd:attribute name="graphDatabaseService" type="graphDatabaseServiceRef" />
|
||||
<xsd:attribute name="base-package" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
comma separated base package(s) for persistent entities.
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="entityManagerFactory" type="xsd:string" use="optional">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
entity manager factory bean reference for cross-store configuration
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="create-index" type="xsd:boolean" use="optional" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
decides if schema and legacy indexes are created upfront for this application, defaults to true
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="repositories">
|
||||
<xsd:complexType>
|
||||
<xsd:complexContent>
|
||||
<xsd:extension base="repository:repositories">
|
||||
<xsd:attribute name="neo4j-template-ref" type="neo4jTemplateRef"/>
|
||||
<xsd:attributeGroup ref="repository:repository-attributes"/>
|
||||
</xsd:extension>
|
||||
</xsd:complexContent>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="auditing">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:exports type="org.springframework.data.neo4j.lifecycle.AuditingEventListener" />
|
||||
<tool:exports type="org.springframework.data.auditing.IsNewAwareAuditingHandler" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attributeGroup ref="repository:auditing-attributes" />
|
||||
<xsd:attribute name="neo4jTemplate" type="mappingContextRef" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
<xsd:simpleType name="neo4jTemplateRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.neo4j.support.Neo4jTemplate"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="mappingContextRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.data.mapping.context.MappingContext"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="graphDatabaseServiceRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.neo4j.graphdb.GraphDatabaseService"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
<xsd:simpleType name="entityManagerFactoryRef">
|
||||
<xsd:annotation>
|
||||
<xsd:appinfo>
|
||||
<tool:annotation kind="ref">
|
||||
<tool:assignable-to type="org.springframework.orm.jpa.AbstractEntityManagerFactoryBean"/>
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
<xsd:union memberTypes="xsd:string"/>
|
||||
</xsd:simpleType>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,80 @@
|
||||
package org.springframework.data.neo4j.config;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
import org.neo4j.graphdb.GraphDatabaseService;
|
||||
import org.neo4j.test.TestGraphDatabaseFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.context.support.FileSystemXmlApplicationContext;
|
||||
import org.springframework.data.neo4j.support.mapping.DefaultEntityIndexCreator;
|
||||
import org.springframework.data.neo4j.support.mapping.EntityIndexCreator;
|
||||
import org.springframework.data.neo4j.support.mapping.NoEntityIndexCreator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author mh
|
||||
* @since 19.10.14
|
||||
*/
|
||||
public class CreateIndexConfigTests {
|
||||
|
||||
private ApplicationContext ctx;
|
||||
|
||||
static class DefaultTestConfiguration extends Neo4jConfiguration {
|
||||
@Bean
|
||||
public GraphDatabaseService graphDatabaseService() {
|
||||
return new TestGraphDatabaseFactory().newImpermanentDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
static class NoIndexTestConfiguration extends Neo4jConfiguration {
|
||||
NoIndexTestConfiguration() {
|
||||
setCreateIndex(false);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GraphDatabaseService graphDatabaseService() {
|
||||
return new TestGraphDatabaseFactory().newImpermanentDatabase();
|
||||
}
|
||||
}
|
||||
@Test
|
||||
public void testEnableIndexWithNoConfig() throws Exception {
|
||||
ctx = new AnnotationConfigApplicationContext(DefaultTestConfiguration.class);
|
||||
EntityIndexCreator entityIndexCreator = ctx.getBean("entityIndexCreator", EntityIndexCreator.class);
|
||||
assertEquals(DefaultEntityIndexCreator.class,entityIndexCreator.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDisableIndexWithConstructorParam() throws Exception {
|
||||
ctx = new AnnotationConfigApplicationContext(NoIndexTestConfiguration.class);
|
||||
EntityIndexCreator entityIndexCreator = ctx.getBean("entityIndexCreator", EntityIndexCreator.class);
|
||||
assertEquals(NoEntityIndexCreator.class,entityIndexCreator.getClass());
|
||||
}
|
||||
@Test
|
||||
public void testDisableIndexWithXmlConfig() throws Exception {
|
||||
ctx = new ClassPathXmlApplicationContext("CreateIndexConfigTests-NoIndex-context.xml",getClass());
|
||||
EntityIndexCreator entityIndexCreator = ctx.getBean("entityIndexCreator", EntityIndexCreator.class);
|
||||
assertEquals(NoEntityIndexCreator.class,entityIndexCreator.getClass());
|
||||
}
|
||||
@Test
|
||||
public void testEnableIndexWithDefaultXmlConfig() throws Exception {
|
||||
ctx = new ClassPathXmlApplicationContext("CreateIndexConfigTests-DefaultIndex-context.xml",getClass());
|
||||
EntityIndexCreator entityIndexCreator = ctx.getBean("entityIndexCreator", EntityIndexCreator.class);
|
||||
assertEquals(DefaultEntityIndexCreator.class,entityIndexCreator.getClass());
|
||||
}
|
||||
@Test
|
||||
public void testEnableIndexWithXmlConfig() throws Exception {
|
||||
ctx = new ClassPathXmlApplicationContext("CreateIndexConfigTests-Index-context.xml",getClass());
|
||||
EntityIndexCreator entityIndexCreator = ctx.getBean("entityIndexCreator", EntityIndexCreator.class);
|
||||
assertEquals(DefaultEntityIndexCreator.class,entityIndexCreator.getClass());
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
if (ctx != null) ctx.close();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,7 @@ public class Neo4jPersistentTestBase {
|
||||
factoryBean.setNodeEntityStateFactory(nodeEntityStateFactory);
|
||||
factoryBean.setRelationshipEntityStateFactory(relationshipEntityStateFactory);
|
||||
|
||||
mappingContext.setEntityIndexCreator(new EntityIndexCreator(new IndexProviderImpl(graphDatabase), new SchemaIndexProvider(graphDatabase),true));
|
||||
mappingContext.setEntityIndexCreator(new DefaultEntityIndexCreator(new IndexProviderImpl(graphDatabase), new SchemaIndexProvider(graphDatabase),true));
|
||||
mappingContext.setSimpleTypeHolder(null);
|
||||
setBasePackage(mappingContext);
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||
http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
|
||||
|
||||
<context:annotation-config/>
|
||||
<neo4j:config storeDirectory="target/test-db" base-package="org.springframework.data.neo4j.config" graphDatabaseService="graphDatabaseService"/>
|
||||
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||
http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
|
||||
|
||||
<context:annotation-config/>
|
||||
<neo4j:config create-index="true" base-package="org.springframework.data.neo4j.config" graphDatabaseService="graphDatabaseService"/>
|
||||
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:neo4j="http://www.springframework.org/schema/data/neo4j"
|
||||
xmlns:tx="http://www.springframework.org/schema/tx"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
|
||||
http://www.springframework.org/schema/data/neo4j http://www.springframework.org/schema/data/neo4j/spring-neo4j.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
|
||||
|
||||
<context:annotation-config/>
|
||||
<neo4j:config storeDirectory="target/test-db" create-index="false" base-package="org.springframework.data.neo4j.config" graphDatabaseService="graphDatabaseService"/>
|
||||
<bean id="graphDatabaseService" class="org.neo4j.test.ImpermanentGraphDatabase"/>
|
||||
</beans>
|
||||
@@ -7,9 +7,9 @@ Neo4j is not only available in embedded mode. It can also be installed and run a
|
||||
|
||||
When should you write a server extension? The default REST API is essentially a REST'ified representation of the Neo4j core API. It is nice for getting started, and for simpler scenarios. For more involved solutions that require high-volume access or more complex operations, writing a server extension that is able to process external parameters, do all the computations locally in the plugin, and then return just the relevant information to the calling client is preferable.
|
||||
|
||||
The Neo4j Server has two built-in extension mechanisms. It is possible to extend existing URI endpoints like the graph database, nodes, or relationships, adding new URIs or methods to those. This is achieved by writing a http://docs.neo4j.org/chunked/milestone/server-plugins.html[server plugin]. This plugin type has some restrictions however.
|
||||
The Neo4j Server has two built-in extension mechanisms. It is possible to extend existing URI endpoints like the graph database, nodes, or relationships, adding new URIs or methods to those. This is achieved by writing a http://neo4j.com/docs/milestone/server-plugins.html[server plugin]. This plugin type has some restrictions however.
|
||||
|
||||
For complete freedom in the implementation, an http://docs.neo4j.org/chunked/milestone/server-unmanaged-extensions.html[unmanaged extension] can be used. Unmanaged extensions are essentially http://jersey.java.net/[Jersey] resource implementations. The resource constructors or methods can get the `GraphDatabaseService` injected to execute the necessary operations and return appropriate `Representations`.
|
||||
For complete freedom in the implementation, an http://neo4j.com/docs/milestone/server-unmanaged-extensions.html[unmanaged extension] can be used. Unmanaged extensions are essentially http://jersey.java.net/[Jersey] resource implementations. The resource constructors or methods can get the `GraphDatabaseService` injected to execute the necessary operations and return appropriate `Representations`.
|
||||
|
||||
Both kinds of extensions have to be packaged as JAR files and added to the Neo4j Server's plugin directory. Server Plugins are picked up by the server at startup if they provide the necessary `META-INF.services/org.neo4j.server.plugins.ServerPlugin` file for Java's ServiceLoader facility. Unmanaged extensions have to be registered with the Neo4j Server configuration.
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ http://neo4j.org/[Neo4j] is a NOSQL graph database. It is a fully transactional
|
||||
|
||||
Neo4j has been in commercial development for 10 years and in production for over 7 years. Most importantly it has a helpful and contributing community surrounding it, but it also:
|
||||
|
||||
* has an intuitive, rich graph-oriented model for data representation. Instead of tables, rows, and columns, you work with a graph consisting of http://docs.neo4j.org/chunked/milestone/what-is-a-graphdb.html[nodes, relationships, and properties]
|
||||
* has an intuitive, rich graph-oriented model for data representation. Instead of tables, rows, and columns, you work with a graph consisting of http://neo4j.com/docs/milestone/what-is-a-graphdb.html[nodes, relationships, and properties]
|
||||
* has a disk-based, native storage manager optimized for storing graph structures with maximum performance and scalability.
|
||||
* is scalable. Neo4j can handle graphs with many billions of nodes/relationships/properties on a single machine, but can also be scaled out across multiple machines for high availability.
|
||||
* has a powerful traversal framework and query languages for traversing the graph.
|
||||
@@ -101,7 +101,7 @@ try (Transaction tx = graphDb.beginTx()) {
|
||||
|
||||
== Querying the Graph with Cypher
|
||||
|
||||
Neo4j provides a graph query language called http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html["Cypher"] which draws from many sources. It resembles SQL but with an iconic representation of patterns in the graph (concepts drawn from SPARQL). The Cypher execution engine was written in Scala to leverage the high expressiveness for lazy sequence operations of the language and the parser combinator library. A screencast explaining the possibilities in detail can be found on the http://video.neo4j.org/ybMbf/screencast-introduction-to-cypher/[Neo4j video site].
|
||||
Neo4j provides a graph query language called http://neo4j.com/docs/milestone/cypher-query-lang.html["Cypher"] which draws from many sources. It resembles SQL but with an iconic representation of patterns in the graph (concepts drawn from SPARQL). The Cypher execution engine was written in Scala to leverage the high expressiveness for lazy sequence operations of the language and the parser combinator library. A screencast explaining the possibilities in detail can be found on the http://video.neo4j.org/ybMbf/screencast-introduction-to-cypher/[Neo4j video site].
|
||||
|
||||
As of Neo4 2.0, Cypher queries typically begin with a `match` clause, although the optional `start` clause (only really needed when using legacy indexes) is also still supported. The `match` clause can be used to provide a way to pattern match against a starting set of nodes, via their IDs or label based index lookup, with the legacy `start` clause providing similar functionality. These starting patterns or start nodes, are then related to other nodes via additional `match` clauses. Start and/or match clauses can introduce new identifiers for nodes and relationships. In the `where` clause additional filtering of the result set is applied by evaluating expressions. The `return` clause defines which part of the query result will be available. Aggregation also happens in the return clause by using aggregation functions on some of the values. Sorting can happen in the `order by` clause and the `skip` and `limit` parts restrict the result set to a certain window.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ The Spring Data Neo4j project, as part of the Spring Data initiative, aims to si
|
||||
|
||||
Spring Data Neo4j allows, at any time, to drop down to the Neo4j-API level, see <<neo4j>> to execute functionality with the highest performance possible.
|
||||
|
||||
For integration of Neo4j and Grails/GORM please refer to the Neo4j http://www.grails.org/plugin/neo4j[grails plugin]. There are also http://docs.neo4j.org/chunked/milestone/python-embedded.html[Python bindings] as well as community-provided bindings to use Neo4j in http://docs.neo4j.org/chunked/milestone/languages.html[embedded] or http://docs.neo4j.org/chunked/milestone/tutorials-rest.html[REST mode].
|
||||
For integration of Neo4j and Grails/GORM please refer to the Neo4j http://www.grails.org/plugin/neo4j[grails plugin]. There are also http://neo4j.com/docs/milestone/python-embedded.html[Python bindings] as well as community-provided bindings to use Neo4j in http://neo4j.com/docs/milestone/languages.html[embedded] or http://neo4j.com/docs/milestone/tutorials-rest.html[REST mode].
|
||||
|
||||
== Reference Documentation Overview
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[[reference_programming-model_indexing]]
|
||||
= Indexing
|
||||
|
||||
Indexing is used in Neo4j to quickly find nodes and relationships to start graph operations from. Either for manually traversing the graph, using the traversal framework, cypher queries or for "global" graph operations. Indexes are also employed to ensure uniqueness of elements with certain properties.
|
||||
Indexing is used in Neo4j to quickly find nodes and relationships to start graph operations from. Either for manually traversing the graph, using the traversal framework, cypher queries or for "global" graph operations. Indexes are also employed to ensure uniqueness of elements with certain labels and properties.
|
||||
|
||||
NOTE: Please note that the lucene based manual indexes are deprecated with Neo4j 2.0 and Spring Data Neo4j 3.0. The default index is now based on labels and schema indexes and the related APIs have been deprecated as well. The "legacy" index framework should only be used for fulltext and spatial indexes which are not currently supported via schema based indexes.
|
||||
NOTE: Please note that the lucene based manual indexes are deprecated with Neo4j 2.0 and Spring Data Neo4j 3.0. The default index is now based on labels and schema indexes and the related old APIs have been deprecated as well. The "legacy" index framework should only be used for fulltext and spatial indexes which are not currently supported via schema based indexes.
|
||||
|
||||
== Schema (Label based) indexes
|
||||
|
||||
@@ -11,6 +11,12 @@ Since Neo4j version 2.0 indexes and unique constraints based on labels and prope
|
||||
|
||||
Those indexes will be automatically used by cypher queries that are generated for the derived finders and are available for custom queries.
|
||||
|
||||
== Index Creation
|
||||
|
||||
Indexes are created and updated upfront, when Spring Data Neo4j scans your entities and detects indexed fields. It will use an instance of `org.springframework.data.neo4j.support.mapping.EntityIndexCreator to create both schema based and legacy indexes.
|
||||
|
||||
For certain setups, e.g. when your system is already set-up with all the indexes or when you run in an HA-cluster against a slave, you can disable this behavior by configuring `<neo4j:config create-index="false" />` or calling `Neo4jConfiguration.setCreateIndex(false)`. The default value is "true".
|
||||
|
||||
== Legacy indexes
|
||||
|
||||
If you would like to force a property on an entity to rather use the legacy index (instead of the default schema based index), then you will need to explicitly specify the type as either `@Indexed(indexType = IndexType.SIMPLE)` or `@Indexed(indexType = IndexType.FULLTEXT)`
|
||||
@@ -96,8 +102,6 @@ Person mark = graphRepository.findAllByQuery("people-search", "name", "ma*");
|
||||
----
|
||||
====
|
||||
|
||||
NOTE: Please note that the legacy indexes are currently created on demand, so whenever an index that doesn't exist is requested from a query or get operation it is created. This is subject to change but has currently the implication that those indexes won't be configured as fulltext which causes subsequent fulltext updates to those indexes to fail.
|
||||
|
||||
== Unique indexes
|
||||
|
||||
Unique indexing can be applied either via the inbuilt schema (label based) unique constraint for nodes, or, via the legacy `index.putIfAbsent` and `UniqueFactory` code for both nodes and relationships. In Spring Data Neo4j this is done by setting the `unique=true` property on the `@Indexed` annotation. Methods for programmatically getting and/or creating unique entities is available on the `Neo4jTemplate` class, namely `getOrCreateNode` and `getOrCreateRelationship` for legacy indexes, and `merge` for schema based unique entities.
|
||||
@@ -209,7 +213,7 @@ For querying the index, the template offers query methods that take either the e
|
||||
|
||||
== Neo4j Auto Indexes
|
||||
|
||||
Neo4j allows to configure http://docs.neo4j.org/chunked/milestone/auto-indexing.html[auto-indexing] for certain properties on nodes and relationships. This auto-indexing differs from the approach used in Spring Data Neo4j because it only updates the indexes when the transaction is committed. So the index modifications will only be available after the successful commit. It is possible to use the specific index names `node_auto_index` and `relationship_auto_index` when querying indexes in Spring Data Neo4j either with the query methods in template and repositories or via Cypher.
|
||||
Neo4j allows to configure (legacy) http://neo4j.com/docs/milestone/auto-indexing.html[auto-indexing] for certain properties on nodes and relationships. This auto-indexing differs from the approach used in Spring Data Neo4j, because there is only one index across all nodes or relationships. It is possible to use the specific index names `node_auto_index` and `relationship_auto_index` when querying indexes in Spring Data Neo4j either with the query methods in template and repositories or via Cypher.
|
||||
|
||||
== Spatial Indexes
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
The repositories provided by Spring Data Neo4j build on the composable repository infrastructure in http://static.springsource.org/spring-data/data-commons/docs/current/reference/html/#repositories[Spring Data Commons]. They allow for interface based composition of repositories consisting of provided default implementations for certain interfaces and additional custom implementations for other methods.
|
||||
|
||||
Spring Data Neo4j repositories support annotated and named queries for the Neo4j http://docs.neo4j.org/chunked/milestone/query-lang.html[Cypher] query-language.
|
||||
Spring Data Neo4j repositories support annotated and named queries for the Neo4j http://neo4j.com/docs/milestone/query-lang.html[Cypher] query-language.
|
||||
|
||||
Spring Data Neo4j comes with typed repository implementations that provide methods for locating node and relationship entities. There are several types of basic repository interfaces and implementations. `CRUDRepository` provides basic operations, `IndexRepository` and `NamedIndexRepository` delegate to Neo4j's internal indexing subsystem for queries, and `TraversalRepository` handles Neo4j traversals.
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Spring Data Neo4j projects can be built using Maven. There are also means to bui
|
||||
|
||||
== Dependencies for Spring Data Neo4j Simple Mapping
|
||||
|
||||
For the simple POJO mapping it is enough to add the `org.springframework.data:spring-data-neo4j:3.0.0.RELEASE` dependency to your project.
|
||||
For the simple POJO mapping it is enough to add the `org.springframework.data:spring-data-neo4j:3.3.0.M1` dependency to your project.
|
||||
|
||||
.Maven dependencies for Spring Data Neo4j
|
||||
====
|
||||
@@ -16,7 +16,7 @@ For the simple POJO mapping it is enough to add the `org.springframework.data:sp
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-neo4j</artifactId>
|
||||
<version>3.0.0.RELEASE</version>
|
||||
<version>3.3.0.M1</version>
|
||||
</dependency>
|
||||
----
|
||||
====
|
||||
@@ -32,8 +32,8 @@ The necessary build plugin to build Spring Data Neo4j projects with Gradle is av
|
||||
sourceCompatibility = 1.6
|
||||
targetCompatibility = 1.6
|
||||
|
||||
springVersion = "3.2.8.RELEASE"
|
||||
springDataNeo4jVersion = "3.0.0.RELEASE"
|
||||
springVersion = "4.0.7.RELEASE"
|
||||
springDataNeo4jVersion = "3.3.0.M1"
|
||||
aspectjVersion = "1.7.4"
|
||||
|
||||
apply from:'https://github.com/SpringSource/spring-data-neo4j/raw/master/build/
|
||||
@@ -110,13 +110,13 @@ The dependency on `spring-data-neo4j-aspects` will transitively pull in the nece
|
||||
<dependency>
|
||||
<groupId>org.springframework.data</groupId>
|
||||
<artifactId>spring-data-neo4j-aspects</artifactId>
|
||||
<version>3.0.0.RELEASE</version>
|
||||
<version>3.3.0.M1</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>1.7.4</version>
|
||||
<version>1.8.2</version>
|
||||
</dependency>
|
||||
----
|
||||
====
|
||||
@@ -134,16 +134,15 @@ Since the advanced mapping uses AspectJ for build-time aspect weaving of entitie
|
||||
<artifactId>aspectj-maven-plugin</artifactId>
|
||||
<version>1.4</version>
|
||||
<dependencies>
|
||||
<!-- NB: You must use Maven 2.0.9 or above or these are ignored (see MNG-2972) -->
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjrt</artifactId>
|
||||
<version>1.7.4</version>
|
||||
<version>1.8.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.aspectj</groupId>
|
||||
<artifactId>aspectjtools</artifactId>
|
||||
<version>1.7.4</version>
|
||||
<version>1.8.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
@@ -166,8 +165,8 @@ Since the advanced mapping uses AspectJ for build-time aspect weaving of entitie
|
||||
<artifactId>spring-data-neo4j-aspects</artifactId>
|
||||
</aspectLibrary>
|
||||
</aspectLibraries>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
----
|
||||
@@ -226,13 +225,27 @@ The XML namespace can be used to configure Spring Data Neo4j. The `config` eleme
|
||||
----
|
||||
====
|
||||
|
||||
.XML configuration with http://docs.neo4j.org/chunked/milestone/server-embedded.html[embedded Neo4j-Server]
|
||||
|
||||
.XML configuration with disabled index creation (e.g. for HA-slave)
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<context:annotation-config/>
|
||||
<neo4j:config
|
||||
storeDirectory="target/config-test"
|
||||
create-index="false"
|
||||
base-package="org.example.domain"/>
|
||||
|
||||
----
|
||||
====
|
||||
|
||||
.XML configuration with http://neo4j.com/docs/milestone/server-embedded.html[embedded Neo4j-Server]
|
||||
====
|
||||
[source,xml]
|
||||
----
|
||||
<context:annotation-config/>
|
||||
|
||||
<bean id="graphDatabaseService" class="org.neo4j.kernel.EmbeddedGraphDatabase"
|
||||
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.support.GraphDatabaseServiceFactoryBean"
|
||||
destroy-method="shutdown">
|
||||
<constructor-arg index="0" value="foo/db" />
|
||||
<constructor-arg index="1">
|
||||
@@ -286,7 +299,7 @@ As Spring Data Neo4j repositories build upon the infrastructure provided by http
|
||||
<neo4j:repositories base-package="org.example.repository"/>
|
||||
|
||||
<!-- with template bean reference -->
|
||||
<neo4j:repositories base-package="org.example.repository" graph-database-context-ref="template"/>
|
||||
<neo4j:repositories base-package="org.example.repository" graph-database-context-ref="template"/>
|
||||
----
|
||||
====
|
||||
|
||||
@@ -322,7 +335,7 @@ public class BasicJavaConfig extends Neo4jConfiguration {
|
||||
----
|
||||
====
|
||||
|
||||
.Java-based bean config initialiation via XML
|
||||
.Java-based bean config initialization via XML
|
||||
====
|
||||
To register the default `@Configuration Neo4jConfiguration` class, as well as Spring's `ConfigurationClassPostProcessor` that transforms the `@Configuration` class to bean definitions via XML.
|
||||
|
||||
@@ -338,9 +351,8 @@ To register the default `@Configuration Neo4jConfiguration` class, as well as Sp
|
||||
|
||||
<bean class="org.springframework.context.annotation.ConfigurationClassPostProcessor"/>
|
||||
|
||||
<bean id="graphDbFactory" class="org.neo4j.graphdb.factory.GraphDatabaseFactory"/>
|
||||
<bean id="graphDatabaseService" scope="singleton" destroy-method="shutdown"
|
||||
factory-bean="graphDbFactory" factory-method="newEmbeddedDatabase">
|
||||
<bean id="graphDatabaseService" class="org.springframework.data.neo4j.support.GraphDatabaseServiceFactoryBean"
|
||||
destroy-method="shutdown">
|
||||
<constructor-arg value="target/config-test"/>
|
||||
</bean>
|
||||
...
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
*_Graphs ahead_*
|
||||
|
||||
Now we needed to figure out how to store our chosen domain model in the chosen database. First we read up about graph databases, in particular our chosen one, http://neo4j.org[Neo4j]. The Neo4j data model consists of nodes and relationships, both of which can have key/value-style properties. What does that mean, exactly? Nodes are the graph database name for records, with property keys instead of column names. That's normal enough. Relationships are the special part. In Neo4j, relationships are first-class citizens, meaning they are more than a simple foreign-key reference to another record, relationships carry information. So we can link together nodes into semantically rich networks. This really appealed to us. Then we found that we were also able to http://docs.neo4j.org/chunked/milestone/indexing.html[index nodes and relationships] by {key, value} pairs. We also found that we could traverse relationships both imperatively using the core API, and declaratively using a query-like http://docs.neo4j.org/chunked/milestone/tutorials-java-embedded-traversal.html[Traversal Description]. Besides those programmatic traversals there was the powerful graph query language called http://docs.neo4j.org/chunked/milestone/cypher-query-lang.html[Cypher]. So lots of ways of working with the graph.
|
||||
Now we needed to figure out how to store our chosen domain model in the chosen database. First we read up about graph databases, in particular our chosen one, http://neo4j.org[Neo4j]. The Neo4j data model consists of nodes and relationships, both of which can have key/value-style properties. What does that mean, exactly? Nodes are the graph database name for records, with property keys instead of column names. That's normal enough. Relationships are the special part. In Neo4j, relationships are first-class citizens, meaning they are more than a simple foreign-key reference to another record, relationships carry information. So we can link together nodes into semantically rich networks. This really appealed to us. Then we found that we were also able to http://neo4j.com/docs/milestone/indexing.html[index nodes and relationships] by {key, value} pairs. We also found that we could traverse relationships both imperatively using the core API, and declaratively using a query-like http://neo4j.com/docs/milestone/tutorials-java-embedded-traversal.html[Traversal Description]. Besides those programmatic traversals there was the powerful graph query language called http://neo4j.com/docs/milestone/cypher-query-lang.html[Cypher]. So lots of ways of working with the graph.
|
||||
|
||||
We also learned that Neo4j is fully transactional and therefore upholds http://en.wikipedia.org/wiki/ACID[ACID] guarantees for our data. Durability is actually a good thing and we didn't have to scale to trillions of users and movies yet. This is unusual for NOSQL databases, but easier for us to get our head around than non-transactional eventual consistency. It also made us feel safe, though it also meant that we had to manage transactions. Something to keep in mind later.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user