Neo4j TimeTree в весенних данных Neo4j 4.0
Я пытаюсь использовать библиотеку timetree в моем проекте data data neo4j 4.0.0.
Как подробно описано на этой странице https://github.com/graphaware/neo4j-timetree, я отредактировал свой файл neo4j.properties, чтобы включить автоматическое присоединение событий, добавить зависимость от времени к моему gradle и установить свойство creationDate. в узле события с типом данных Long. Хотя все выглядит так, как должно быть, оно все равно не создает никакого временного дерева.
Вот мой файл neo4j.property:
# Runtime must be enabled like this
com.graphaware.runtime.enabled=true
# A Runtime module that takes care of attaching the events like this (TT is the ID of the module)
com.graphaware.module.TT.1=com.graphaware.module.timetree.module.TimeTreeModuleBootstrapper
# Nodes which represent events and should be attached automatically have to be defined
com.graphaware.module.TT.event=hasLabel('StructureVersionChange'),hasLabel('RuleVersionChange'),hasLabel('FilterVersionChange')
# Optionally, a property on the event nodes that represents the the time (long) at which the event took place must be specified (defaults to "timestamp")
com.graphaware.module.TT.timestamp=creationDate
# Optionally, a resolution can be specified (defaults to DAY)
com.graphaware.module.TT.resolution=SECOND
# Optionally, a time zone can be specified (defaults to UTC)
com.graphaware.module.TT.timezone=CEST
# Optionally, a relationship type with which the events will be attached to the tree can be specified (defaults to AT_TIME)
com.graphaware.module.TT.relationship=CREATED_ON
# autoAttach must be set to true
com.graphaware.module.TT.autoAttach=true
На самом деле, до этого я пытался использовать версию Timetree для JAVA API для моего проекта, но потом меня по-настоящему смутил тип параметра конструктора timetree, который называется Node. Принимая во внимание, что весной мои узлы имеют типы своих классов.
Заранее спасибо, и ваше предложение будет очень признателен!
РЕДАКТИРОВАТЬ:
neo4j.properties
# Runtime must be enabled like this
com.graphaware.runtime.enabled=true
# A Runtime module that takes care of attaching the events like this (TT is the ID of the module)
com.graphaware.module.TT.1=com.graphaware.module.timetree.module.TimeTreeModuleBootstrapper
# Nodes which represent events and should be attached automatically have to be defined
com.graphaware.module.TT.event=hasLabel('FilterVersionChange') || hasLabel('StructureVersionChange') || hasLabel('CodeUnitVersionChange') || hasLabel('RuleVersionChange') || hasLabel('EpisodeVersion')
# Optionally, a property on the event nodes that represents the the time (long) at which the event took place must be specified (defaults to "timestamp")
com.graphaware.module.TT.timestamp=creationDate
# Optionally, a resolution can be specified (defaults to DAY)
com.graphaware.module.TT.resolution=SECOND
# Optionally, a time zone can be specified (defaults to UTC)
com.graphaware.module.TT.timezone=CEST
# Optionally, a relationship type with which the events will be attached to the tree can be specified (defaults to AT_TIME)
com.graphaware.module.TT.relationship=CREATED_ON
# autoAttach must be set to true
com.graphaware.module.TT.autoAttach=true
данные / Журнал /neo4j.0.0
May 17, 2015 4:07:42 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM'
May 17, 2015 4:07:42 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM'
May 17, 2015 4:07:43 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM'
May 17, 2015 4:11:39 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM'
May 17, 2015 4:11:39 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM'
May 17, 2015 4:11:39 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM'
May 17, 2015 4:28:49 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM'
May 17, 2015 4:28:49 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM'
May 17, 2015 4:28:49 PM com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.18.1 02/19/2014 03:28 AM'
данные /graph.db/ сообщения
2015-05-17 14:28:46.537+0000 INFO [o.n.k.i.DiagnosticsManager]: --- INITIALIZED diagnostics START ---
2015-05-17 14:28:46.538+0000 INFO [o.n.k.i.DiagnosticsManager]: Neo4j Kernel properties:
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.resolution=DAY
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.timestamp=creationDate
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.relationship=CREATED_ON
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.event=hasLabel('FilterVersionChange') || hasLabel('ArchitectureUnitVersionChange') || hasLabel('CodeUnitVersionChange') || hasLabel('RuleVersionChange') || hasLabel('EpisodeVersion')
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: store_dir=C:\NEO4J-~1.1\data\graph.db
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.runtime.enabled=true
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.autoAttach=true
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: remote_shell_enabled=true
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.timezone=CEST
2015-05-17 14:28:46.541+0000 INFO [o.n.k.i.DiagnosticsManager]: com.graphaware.module.TT.1=com.graphaware.module.timetree.module.TimeTreeModuleBootstrapper
2015-05-17 14:28:46.544+0000 INFO [o.n.k.i.DiagnosticsManager]: Diagnostics providers:
2015-05-17 14:28:46.544+0000 INFO [o.n.k.i.DiagnosticsManager]: org.neo4j.kernel.configuration.Config
...
...
2015-05-17 14:28:48.656+0000 INFO [o.n.k.i.DiagnosticsManager]: --- STARTED diagnostics for KernelDiagnostics:StoreFiles END ---
2015-05-17 14:28:48.696+0000 INFO [o.n.k.EmbeddedGraphDatabase]: Database is now ready
2015-05-17 14:28:48.696+0000 INFO [o.n.s.d.LifecycleManagingDatabase]: Successfully started database
2015-05-17 14:28:48.699+0000 INFO [o.n.k.i.DiagnosticsManager]: --- SERVER STARTED START ---
2015-05-17 14:28:48.736+0000 INFO [o.n.s.CommunityNeoServer]: Starting HTTP on port :7474 with 8 threads available
2015-05-17 14:28:48.872+0000 INFO [o.n.s.CommunityNeoServer]: Enabling HTTPS on port :7473
2015-05-17 14:28:48.989+0000 INFO [o.n.s.w.Jetty9WebServer]: Mounting static content at [/webadmin] from [webadmin-html]
2015-05-17 14:28:49.023+0000 INFO [o.n.s.w.Jetty9WebServer]: Mounting static content at [/browser] from [browser]
2015-05-17 14:28:49.956+0000 INFO [o.n.s.CommunityNeoServer]: Server started on: http://localhost:7474/
2015-05-17 14:28:49.956+0000 INFO [o.n.s.CommunityNeoServer]: Remote interface ready and available at [http://localhost:7474/]
2015-05-17 14:28:49.956+0000 INFO [o.n.k.i.DiagnosticsManager]: --- SERVER STARTED END ---
Класс Entity
@NodeEntity
public class FilterVersionChange extends UnitVersion {
@GraphId
private Long id;
public FilterVersionChange() {
super();
}
public FilterVersionChange(String description, Date creationDate)
{
super(description, creationDate);
}
@Relationship(type="CONTAINS", direction = Relationship.OUTGOING)
private Set<FilterState> filterStates;
@Relationship(type="PREVIOUS", direction = Relationship.OUTGOING)
private FilterVersionChange previousFilterVersionChange;
@Relationship(type="REFERENCES", direction = Relationship.OUTGOING)
private FilterVersionChange referencedFilterVersionChange;
@Relationship(type="ADDED", direction = Relationship.OUTGOING)
private Set<FilterState> newFilterStates;
@Relationship(type="DELETED", direction = Relationship.OUTGOING)
private Set<FilterState> deletedFilterStates;
@Relationship(type="MODIFIED", direction = Relationship.OUTGOING)
private Set<ModifiedUnitState> modifiedFilterStates;
public void contains(Set<FilterState> filterStates) {
this.filterStates = filterStates;
}
public void previous(FilterVersionChange previousFilterVersionChange) {
this.previousFilterVersionChange = previousFilterVersionChange;
}
public void references(FilterVersionChange referencedFilterVersionChange) {
this.referencedFilterVersionChange = referencedFilterVersionChange;
}
public void added(Set<FilterState> newFilterStates) {
this.newFilterStates = newFilterStates;
}
public void deleted(Set<FilterState> deletedFilterStates) {
this.deletedFilterStates = deletedFilterStates;
}
public void modified(Set<ModifiedUnitState> modifiedFilterStates) {
this.modifiedFilterStates = modifiedFilterStates;
}
}
вместилище
@Repository
public interface FilterVersionRepository extends GraphRepository<FilterVersion> {
@Query("MATCH (project:Project {name:{0}})-[:HAS_FILTER_VERSION]->(filterVersion:FilterVersion {name:{1}}) RETURN filterVersion")
FilterVersion findFilterVersionByName(String projectName, String filterVersionName);
}
Функция вызова
public FilterVersionChange createNewFilterVersionChange(String projectName,
String filterVersionName,
String filterVersionChangeDescription,
Set<FilterState> filterStates)
{
FilterVersion filterVersion = filterVersionRepository.findFilterVersionByName(projectName, filterVersionName);
if(filterVersion != null)
{
for(FilterState filterState : filterStates)
{
Filter filter = new Filter(filterState.getMatchingString(), filterState.getMatchingType());
filterState.stateOf(filter);
}
Set<FilterVersionChange> filterVersionChanges = new HashSet<FilterVersionChange>();
FilterVersionChange filterVersionChange = new FilterVersionChange(filterVersionChangeDescription, new Date());
filterVersionChange.contains(filterStates);
filterVersionChange.added(filterStates);
filterVersionChanges.add(filterVersionChange);
filterVersion.tracks(filterVersionChanges);
filterVersionRepository.save(filterVersion);
return filterVersionChange;
}
else
{
return null;
}
}
FilterVersion.class
@NodeEntity
public class FilterVersion {
@GraphId
private Long id;
private String name;
private String description;
private Date creationDate;
public FilterVersion() {
}
public FilterVersion(String name, String description, Date creationDate) {
this.name = name;
this.description = description;
this.creationDate = creationDate;
}
@Relationship(type = "TRACKS", direction = Relationship.OUTGOING)
private Set<FilterVersionChange> filterVersionChanges;
@Relationship(type = "HAS_FILTER_VERSION", direction = Relationship.INCOMING)
private Project project;
public void setName(String name) {
this.name = name;
}
public void setDescription(String description) {
this.description = description;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public void tracks(Set<FilterVersionChange> filterVersionChanges) {
this.filterVersionChanges = filterVersionChanges;
}
public void belongsTo(Project project) {
this.project = project;
}
public Project getProject() {
return project;
}
}
UnitVersion.class
@NodeEntity
public class UnitVersion {
@GraphId
protected Long id;
private String description;
private Long creationDate;
public UnitVersion() {
}
public UnitVersion(String description, Date creationDate) {
this.description = description;
this.creationDate = creationDate.getTime();
}
@Relationship(type = "MAPPED_ON", direction = Relationship.OUTGOING)
private UnitVersion unitVersion;
public void setDescription(String description) {
this.description = description;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate.getTime();
}
public void mappedOn(UnitVersion unitVersion) {
this.unitVersion = unitVersion;
}
}
2 ответа
Зависимость полезна, только если вы используете временное дерево программно. Если ваше приложение работает на сервере Neo4j, вам необходимо скачать и сохранить его в каталоге плагинов для сервера Neo4j:
a) Платформа GraphAware (выберите Сообщество или Предприятие)
б) модуль TimeTree
Оба могут быть загружены с http://graphaware.com/products/
Без этого, даже с конфигурацией в neo4j.properties, GraphAware Runtime не запускается и временное дерево не будет работать.
Если вы хотите запустить свой код с помощью теста, то вам нужно включить зависимости для TimeTree и GraphAware Runtime и самостоятельно запустить GraphAware Runtime, используя такой код:
GraphAwareRuntime runtime = GraphAwareRuntimeFactory.createRuntime(getDatabase());
runtime.registerModule(new TimeTreeModule("timetree",
TimeTreeConfiguration
.defaultConfiguration()
.with(new NodeInclusionPolicy() {
@Override
public boolean include(Node node) {
return node.hasLabel(DynamicLabel.label("User"));
}
})
})
.withRelationshipType(DynamicRelationshipType.withName("CREATED_ON"))
.withTimeZone(DateTimeZone.forTimeZone(TimeZone.getTimeZone("GMT+1")))
.withTimestampProperty("createdOn")
.withResolution(Resolution.DAY)
,
getDatabase()));
runtime.start();
Затем вы можете написать тесты, такие как
@Test
public void shouldSaveUser()
{
User user = new User( "Michal" );
user.setCreatedOn(1431937636995l);
userRepository.save( user );
assertSameGraph( getDatabase(), "CREATE (u:User:Person {name:'Michal', createdOn:1431937636995})," +
"(root:TimeTreeRoot)," +
"(root)-[:FIRST]->(year:Year {value:2015})," +
"(root)-[:CHILD]->(year)," +
"(root)-[:LAST]->(year)," +
"(year)-[:FIRST]->(month:Month {value:5})," +
"(year)-[:CHILD]->(month)," +
"(year)-[:LAST]->(month)," +
"(month)-[:FIRST]->(day:Day {value:18})," +
"(month)-[:CHILD]->(day)," +
"(month)-[:LAST]->(day)," +
"(day)<-[:CREATED_ON]-(u)"
);
}
Определение возможных меток для TimeTree имеет немного иной синтаксис, как описано в документации InclusionPolicy https://github.com/graphaware/neo4j-framework/tree/master/common
Синтаксис следующий:
com.graphaware.module.TT.event=hasLabel('StructureVersionChange')||hasLabel('RuleVersionChange')||hasLabel('FilterVersionChange')
В целях отладки вы можете добавить эти строки в файл conf/custom-logback.xml:
<appender name="EXTENSIONLOG" class="ch.qos.logback.core.FileAppender">
<file>data/log/extensions.log</file>
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSSZ} %-5level [%logger{15}]: %message%n</pattern>
</encoder>
</appender>
<logger name="com.graphaware" level="debug">
<appender-ref ref="EXTENSIONLOG"/>
</logger>
и посмотрите на файл extensions.log