Neo4j TimeTree REST API Предыдущая и следующая навигация

В настоящее время я использую Neo4j TimeTree REST API, и есть ли способ перейти ко времени до и после заданной метки времени? Мое разрешение - секунда, и я просто понимаю, что если минута изменилась, то нет отношения «СЛЕДУЮЩИЙ», соединяющего предыдущую секунду в предыдущей минуте с текущей секундой. Это делает запрос шифрования довольно сложным, и я просто не хочу снова изобретать велосипед, если он уже доступен. Заранее спасибо, и ваш ответ будет очень ценен!

РЕДАКТИРОВАТЬ

Мне нужно снова воспроизвести отсутствующую проблему отношения NEXT, как вы можете видеть на рисунке ниже. Это начинает происходить с третьего раза, когда я добавляю новый второй момент времени.

введите здесь описание изображения

На самом деле я создаю NodeEntity для работы со вторыми узлами. Класс, как показано ниже.

@NodeEntity(label = "Second")
public class TimeTreeSecond {
    @GraphId
    private Long id;

    private Integer value;

    @Relationship(type = "CREATED_ON", direction = Relationship.INCOMING)
    private FilterVersionChange relatedFilterVersionChange;

    @Relationship(type = "NEXT", direction = Relationship.OUTGOING)
    private TimeTreeSecond nextTimeTreeSecond;

    @Relationship(type = "NEXT", direction = Relationship.INCOMING)
    private TimeTreeSecond prevTimeTreeSecond;

    public TimeTreeSecond() {
    }

    public Long getId() {
        return id;
    }

    public void next(TimeTreeSecond nextTimeTreeSecond) {
        this.nextTimeTreeSecond = nextTimeTreeSecond;
    }

    public FilterVersionChange getRelatedFilterVersionChange() {
        return relatedFilterVersionChange;
    }
}

Проблема здесь заключается в отношениях Incoming NEXT. Когда я опускаю это, все работает нормально. Иногда я даже получаю такое исключение в своей консоли, когда я повторно создаю момент времени с небольшой задержкой.

Exception in thread "main" org.neo4j.ogm.session.result.ResultProcessingException: Could not initialise response
    at org.neo4j.ogm.session.response.GraphModelResponse.<init>(GraphModelResponse.java:38)
    at org.neo4j.ogm.session.request.SessionRequestHandler.execute(SessionRequestHandler.java:55)
    at org.neo4j.ogm.session.Neo4jSession.load(Neo4jSession.java:108)
    at org.neo4j.ogm.session.Neo4jSession.load(Neo4jSession.java:100)
    at org.springframework.data.neo4j.repository.GraphRepositoryImpl.findOne(GraphRepositoryImpl.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.executeMethodOn(RepositoryFactorySupport.java:452)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:437)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:409)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at com.sun.proxy.$Proxy32.findOne(Unknown Source)
    at de.rwthaachen.service.core.FilterDefinitionServiceImpl.createNewFilterVersionChange(FilterDefinitionServiceImpl.java:100)
    at sampleapp.FilterLauncher.main(FilterLauncher.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: org.neo4j.ogm.session.result.ResultProcessingException: "errors":[{"code":"Neo.ClientError.Statement.InvalidType","message":"Expected a numeric value for empty iterator, but got null"}]}
    at org.neo4j.ogm.session.response.JsonResponse.parseErrors(JsonResponse.java:128)
    at org.neo4j.ogm.session.response.JsonResponse.parseColumns(JsonResponse.java:102)
    at org.neo4j.ogm.session.response.JsonResponse.initialiseScan(JsonResponse.java:46)
    at org.neo4j.ogm.session.response.GraphModelResponse.initialiseScan(GraphModelResponse.java:66)
    at org.neo4j.ogm.session.response.GraphModelResponse.<init>(GraphModelResponse.java:36)
    ... 27 more
2015-05-23 01:30:46,204  INFO ork.data.neo4j.config.Neo4jConfiguration:  62 - Intercepted exception

Ниже приведен один пример вызова REST, который я использую для создания узлов мгновенного времени: nofollow noreferrer">http://localhost:7474/graphaware/timetree/1202/single/1432337658713?resolution=Second&timezone=Europe/Amsterdam

метод, который я использую для создания данных:

public FilterVersionChange createNewFilterVersionChange(String projectName,
                                                            String filterVersionName,
                                                            String filterVersionChangeDescription,
                                                            Set<FilterState> filterStates)
    {
        Long filterVersionNodeId = filterVersionRepository.findFilterVersionByName(projectName, filterVersionName);
        FilterVersion newFilterVersion = filterVersionRepository.findOne(filterVersionNodeId, 2);

        // Populate all the existing filters in the current project
        Map<String, Filter> existingFilters = new HashMap<String, Filter>();
        try
        {
            for(Filter filter : newFilterVersion.getProject().getFilters())
            {
                existingFilters.put(filter.getMatchingString(), filter);
            }
        }
        catch(Exception e) {}

        // Map the filter states to the populated filters, if any. Otherwise, create new filter for it.
        for(FilterState filterState : filterStates)
        {
            Filter filter = existingFilters.get(filterState.getMatchingString());
            if(filter == null)
            {
                filter = new Filter(filterState.getMatchingString(), filterState.getMatchingType(), newFilterVersion.getProject());
            }
            filterState.stateOf(filter);
        }

        Long now = System.currentTimeMillis();
        TimeTreeSecond timeInstantNode = timeTreeSecondRepository.findOne(timeTreeService.getFilterTimeInstantNodeId(projectName, now));
        FilterVersionChange filterVersionChange = new FilterVersionChange(filterVersionChangeDescription, now, filterStates, filterStates, newFilterVersion, timeInstantNode);
        FilterVersionChange addedFilterVersionChange = filterVersionChangeRepository.save(filterVersionChange);

        return addedFilterVersionChange;
    }

person Peter Sie    schedule 22.05.2015    source источник
comment
Сможете ли вы запустить этот запрос в своем браузере и получить результаты: ПОИСКПОЗ (n: второй {значение: 42}), (n2: второй {значение: 21}) ПОИСКПОЗ (n) - [r: СЛЕДУЮЩИЙ] - ( n2) ВОЗВРАТ n, n2, type(r) спасибо   -  person Christophe Willemsen    schedule 23.05.2015
comment
@ChristopheWillemsen, этот запрос не возвращает строк.   -  person Peter Sie    schedule 23.05.2015
comment
Спасибо, мы продолжим расследование, можете ли вы предоставить запрос, который вы используете, или 3 отметки времени, используемые для остальных API, чтобы воспроизвести проблему.   -  person Christophe Willemsen    schedule 23.05.2015
comment
Итак, вы создаете свои события из связанной сущности FilterVersionChange?   -  person Christophe Willemsen    schedule 23.05.2015
comment
@ChristopheWillemsen да. Поэтому я запрашиваю узел мгновенного времени с остальным API, затем прикрепляю FilterVersionChange к вновь созданному узлу мгновенного времени с репозиторием Spring.   -  person Peter Sie    schedule 23.05.2015
comment
Есть ли возможность использовать JAVA API библиотеки timetree из Spring Data Neo4j? Я действительно хочу использовать JAVA API, но меня смущают различия типов с Spring Data Neo4j.   -  person Peter Sie    schedule 23.05.2015
comment
Не могли бы вы опубликовать: точные версии Neo4j, GraphAware Framework, TimeTree и SDN, которые вы используете, и последовательность, в которой вы выполняете все, что вы выполняете, чтобы добраться до точки на вашем снимке экрана? Под этим я подразумеваю, например: выполнить вызов rest для X, затем загрузить объект, используя этот и этот метод в SDN, и т. д. Ура!   -  person Michal Bachman    schedule 23.05.2015
comment
А также метод, содержащий эту строку: FilterDefinitionServiceImpl.createNewFilterVersionChange(FilterDefinitionServiceImpl.java:100)   -  person Luanne    schedule 23.05.2015
comment
@MichalBachman Я программирую свое приложение с помощью Spring Data Neo4j 4.0.0.BUILD_SNAPSHOT, Neo4j Community 2.2.1 (установка в формате zip), Neo4j TimeTree 2.2.1.30.21 и GraphAware Server Community 2.2.1.30. Итак, последовательность такова: я создаю узел мгновенного времени с помощью вызова rest, получаю его идентификатор узла, запрашиваю этот вновь созданный узел мгновенного времени с помощью функции findOne из репозитория класса TimeTreeSecond, который я написал выше, затем прикрепляю свой узел события к этот мгновенный узел времени. и, наконец, сохраните узел событий, используя функцию сохранения репозитория узла событий. Надеюсь, что это дает достаточно информации.   -  person Peter Sie    schedule 23.05.2015
comment
@Luanne Я отредактировал свой пост и включил нужный вам метод.   -  person Peter Sie    schedule 23.05.2015
comment
Спасибо, Питер, я смогу посмотреть на это на следующей неделе.   -  person Luanne    schedule 23.05.2015


Ответы (2)


Оставив на мгновение в стороне конкретное использование TimeTree, я хотел бы описать, как в целом управлять двусвязным списком с помощью SDN 4, особенно для случая, когда базовый граф использует один тип отношений между узлами, например.

(post:Post)-[:NEXT]->(post:Post)

Чего нельзя делать

Из-за ограничений в структуре сопоставления невозможно надежно объявить один и тот же тип отношения дважды в двух разных направлениях в вашей объектной модели, т.е. это (в настоящее время) не будет работать:

class Post {
   @Relationship(type="NEXT", direction=Relationship.OUTGOING)
   Post next;

   @Relationship(type="NEXT", direction=Relationship.INCOMING)
   Post previous;
}

Что вы можете сделать

Вместо этого мы можем комбинировать аннотацию @Transient с использованием аннотированных методов установки для получения желаемого результата:

class Post {
   Post next;

   @Transient Post previous;

   @Relationship(type="NEXT", direction=Relationship.OUTGOING)
   public void setNext(Post next) {
      this.next = next;
      if (next != null) {
          next.previous = this;
      }
   }
}

Наконец, если вы хотите иметь возможность перемещаться вперед и назад по всему списку сообщений из любого начального сообщения без необходимости постоянно обновлять их из базы данных, вы можете установить глубину выборки на -1 при загрузке пост, например:

findOne(post.getId(), -1);

Имейте в виду, что запрос бесконечной глубины будет извлекать каждый достижимый объект в графе из совпадающего, поэтому используйте его с осторожностью!

Надеюсь, это полезно

person Vince    schedule 24.05.2015
comment
Это ограничение, как я и думал, от SDN4. Спасибо за ваше объяснение, и я попробую ваше решение. Я думаю, что не буду пытаться получить с опцией -1, это слишком рискованно, потому что размер моего графика очень большой и все связаны. Надеемся, что функция двунаправленной навигации между узлами одного и того же типа станет возможной в грядущей SDN. - person Peter Sie; 24.05.2015

Секунды связаны друг с другом отношением NEXT, даже через минуты.

Надеюсь, это то, что вы имели в виду введите здесь описание изображения

person Luanne    schedule 22.05.2015
comment
О, я думаю, что я слишком устал, чтобы видеть линии моего графика. Потому что раньше я был действительно уверен, что между секундами и минутами нет связи «СЛЕДУЮЩИЙ». Но теперь, когда я стираю свою базу данных и пытаюсь снова, она там. Извините за эту путаницу. Я могу удалить эту тему, если это необходимо. - person Peter Sie; 22.05.2015
comment
еще вопрос, можно ли с помощью REST API удалить конкретный момент времени из дерева? Я вижу, что он доступен в функциях JAVA API, но не могу найти никаких инструкций для REST API. Спасибо! - person Peter Sie; 22.05.2015
comment
Нет, на данный момент он не доступен через API REST, но не стесняйтесь отправлять PR :-) - person Luanne; 22.05.2015