Что Эрик сказал правильно, когда дело доходит до того, что внутренние ID-устройства Neo4j могут быть переработаны.
Мы начали добавлять поддержку SDN, чтобы помочь разработчикам обойти это. Мы можем сделать это на нескольких примерах.
Пример 1: Если у вас есть естественный ID
Допустим, у нас есть объект домена User
и однозначно идентифицировать полем называется email
. Мы могли бы создать нашу модель так:
@NodeEntity
public class User {
@GraphId
private Long id;
@Index(unique=true, primary=true)
private String email;
...
}
Затем мы можем иметь хранилище создать как таковые:
public interface UserRepository extends CrudRepository<User, String> {
}
Обратите внимание, как последнее значением в параметризованном типе является строкой. Это представляет собой первичный индекс, используемый для этого класса.
Теперь вы можете сделать что-то вроде:
User user = userRepository.findOne("[email protected]");
Посмотрите, как вы можете просто передать в основной идентификатор для класса?
Пример 2: Если вам нужен синтетический ID
Допустим, пользователь мы определили выше, имеет твитов. Поскольку нет никакого естественного идентификатора для твита, мы даем его. Лучший способ избежать столкновения с ID - использовать UUID типа 4. К счастью, Java поставляется с предварительной загрузкой UUID, и SDN поддерживает ее сохранение.
import org.neo4j.ogm.annotation.typeconversion.Convert;
import org.neo4j.ogm.typeconversion.UuidStringConverter;
import java.util.UUID;
@NodeEntity
public class Tweet {
@GraphId
private Long id;
@Convert(UuidStringConverter.class)
@Index(unique = true, primary = true)
private UUID uuid;
...
public Tweet(String message) {
this.uuid = UUID.randomUUID();
// other initialisation.
}
}
Итак, что мы имеем здесь UUID
назначен любой созданный чирикать. Затем это можно сохранить в базе данных через конвертер. Удобная вещь в том, что для установки нет дополнительных библиотек. Также гарантируется (ну, по большей части!), Чтобы никогда не было проблем, с которыми сталкиваются внутренние идентификаторы Neo4j. Про (или con) - это идентификаторы, которые производятся, чтобы быть универсально уникальными по вашему приложению.
Если вы хотите, чтобы база данных всегда генерировала UUID, я также рекомендовал бы плагин GraphAware https://github.com/graphaware/neo4j-uuid.
Опять Tweet Repository может воспользоваться этим:
public interface TweetRepository extends CrudRepository<Tweet, UUID> {
}
Теперь вы можете сделать что-то вроде:
Tweet tweet = tweetRepository.findOne(UUID.fromString("0f6e7004-cefc-4397-b4d2-078c1370856a"));
Заключительное примечание; на момент написания @Indexed(unique=true,primary=true)
может быть изменен просто называться @Id
в SDN 5.0.
Благодарим за подробный ответ! Один последующий вопрос о запросе Cypher и 'UUID'. Раньше в качестве параметров для моего запроса Cypher я использовал 'Ids (@GraphId)' и следующие операторы - например, где 'WHERE ID (p) в {productIds}'. Прямо сейчас вместо внутренних идентификаторов мне нужно передать набор 'UUID'. Как правильно использовать эти 'UUID' в Cypher -' ID (p) IN {productUUIDs} 'или simlpe' p IN {productUUIDs} '. Кроме того, есть ли разница в производительности с точки зрения производительности между 'GraphId' и' @Index (unique = true, primary = true) private UUID uuid'? – alexanoid
Вы должны иметь возможность сделать что-то вроде 'WHERE p.uuid IN {productUuids}', где 'productUuids' являются представлениями String. Я не уверен, что мы поддерживаем преобразование параметров методов репозитория на данный момент, но мы будем в следующем выпуске. Что касается производительности, если вы включаете autoindexing или вы уже проиндексировали свойство uuid этого ярлыка, тогда он должен быть очень быстрым, поскольку поиск выполняется с помощью индексов. – digx1