Хороший способ понять, что происходит, - добавить logging.level.org.neo4j.ogm.drivers.bolt=DEBUG
к вашему application.properties.Это даст вам фактический шифр, выполняемый в журналах.Вы можете видеть, что ваш код преобразуется в операторы MERGE
, как показано ниже.
Request: UNWIND {rows} as row MERGE (n:`Vehicle`{name: row.props.name}) SET n=row.props RETURN row.nodeRef as ref, ID(n) as id, {type} as type with params {type=node, rows=[{nodeRef=-1, props={name=Car}}]}
Request: UNWIND {rows} as row MERGE (n:`Part`{name: row.props.name}) SET n=row.props RETURN row.nodeRef as ref, ID(n) as id, {type} as type with params {type=node, rows=[{nodeRef=-3, props={name=brake}}, {nodeRef=-5, props={name=accelerator}}, {nodeRef=-7, props={name=clutch}}]}
Предложение MERGE
гарантирует наличие шаблона на графике.Либо шаблон уже существует, либо его необходимо создать.Он не удалит существующие узлы.
Принимая решение, есть несколько различных способов достижения того, что вы ищете, наивным решением было бы сделать что-то вроде ниже:
Part p = new Part("brake");
partRepository.delete(p);
Тем не менее, обратите внимание, что это удалит все детали с именем «тормоз» против ВСЕХ узлов автомобиля.Который может быть не то, что вы хотите всегда.Например,Вы можете отсоединить clutch
только от автомобилей с именем Car
.
Скажем, у вас есть свойство name
на этикетке автомобиля, вы можете сделать что-то подобное в своем коде, чтобы отсоединить иудалить сцепление из Vehicle
с именем Car
(если у вас нет имени для Vehicle, используйте id или другое уникальное свойство):
Vehicle car = vehicleRepository.findByName("Car");
for(Part p: car.getParts()){
if("clutch".equalsIgnoreCase(p.getName())){
partRepository.delete(p);
}
}
Другой вариант - написать метод в вашемVehicleRepository с аннотацией @Query
для выполнения эквивалента запроса ниже:
MATCH(n:Vehicle {name:"Car"})-[:HAS_PART]->(p:Part{ name:"brake"})
DETACH DELETE p
Затем вы можете просто вызвать его из своего класса обслуживания.
См. здесь для примеров.
Редактировать: Добавление дополнительной информации об удалении только связи между транспортным средством и деталью.
Это можно сделать, написавпользовательский запрос в VehicleRepository, как показано ниже (я предполагаю, что у вас также есть свойство name в Vehicle, если вы не можете использовать id вместо имени):
@Query("MATCH(n:Vehicle {name: {0}})-[r:HAS_PART]-(p:Part{ name:{1}}) DELETE r")
Vehicle detachPartFromVehicle(@Param("partName") String vehicleNameName, @Param("partName") String partName);
Теперь из вашего кода вы можете просто вызватьэто, например .:
vehicleRepository.detachPartFromVehicle("Car", "clutch");
Это должно привести кпри удалении отношения HAS_PART
- часть clutch
останется на графике, но будет отключена от автомобиля Car
.
Кроме того, вы можете отключить несколько частей, преобразовав их вВ запросе:
@Query("MATCH(n:Vehicle {name: {0}})-[r:HAS_PART]-(p:Part) WHERE p.name IN {1} DELETE r")
Vehicle detachPartFromVehicle(@Param("partName") String vehicleNameName, @Param("partNames") String[] partNames);
.
vehicleRepository.detachPartFromVehicle("Car", new String[] {"clutch", "brake"});