Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
03-01-2021 04:40 PM
Hello one and all, in a departure from my normal form, the code here seems to work; but I am just looking for some counsel to perhaps add a little more elegance.
org.springframework.data:spring-data-neo4j:6.0.5
kotlin 1.4.30
I lead an active life and so I have decided to keep a record of it.
So I have a diary
@Node
data class Diary constructor(@Id @GeneratedValue val id: Long? = null, val name: String, @Relationship(type = "DIARY_TO_ENTRY") val entriesList: List<Entry>)
and an Entry
@Node
data class Entry constructor(@Id @GeneratedValue val id: Long? = null, val localDate: LocalDate, val activity: String)
I have also started to add a few items into my diary
@SpringBootApplication
class DogyearsApplication {
fun <T : Any> Optional<T>.asNonNullable(): T = this.orElseThrow()
@Bean
fun init(diaryRepository: DiaryRepository, entryRepository: EntryRepository): CommandLineRunner {
return CommandLineRunner {
val ld_2000Jan01: LocalDate = LocalDate.of(2000, Month.JANUARY, 1)
val ld_2000Jan02: LocalDate = LocalDate.of(2000, Month.JANUARY, 2)
val ld_2000Jan03: LocalDate = LocalDate.of(2000, Month.JANUARY, 3)
val barkAtMailCarrier = "bark at mail carrier"
val chaseSquirrel = "chase squirrel"
val hideFromCat = "hide from cat"
val entryJan01BarkAtMailCarrier = Entry(localDate = ld_2000Jan01, activity = barkAtMailCarrier)
val entryJan01ChaseSquirrel = Entry(localDate = ld_2000Jan01, activity = chaseSquirrel)
val entryJan02BarkAtMailCarrier = Entry(localDate = ld_2000Jan02, activity = barkAtMailCarrier)
val entryJan02HideFromCat = Entry(localDate = ld_2000Jan02, activity = hideFromCat)
diaryRepository.deleteAll()
entryRepository.deleteAll()
val diary = Diary(
name="Rover",
entriesList = listOf<Entry>
(entryJan01BarkAtMailCarrier, entryJan01ChaseSquirrel, entryJan02BarkAtMailCarrier,
entryJan02HideFromCat)
)
val savedDiary = diaryRepository.save<Diary>(diary)
val diaryId = savedDiary.id
Now, if I wished to add further entries
val entryJan03BarkAtMailCarrier = Entry(localDate = ld_2000Jan03, activity = barkAtMailCarrier)
val entryJan03ChaseSquirrel = Entry(localDate = ld_2000Jan03, activity = chaseSquirrel)
I think there would be two ways to skin a cat, if you forgive my anti-feline sentiments.
Either I could read the whole diary into the Kotlin code, add an entry to the list and then save it again
val readDiary = diaryRepository.findById(diaryId!!).asNonNullable()
val extendedDiary = readDiary.copy(entriesList = readDiary.entriesList.plus(entryJan03BarkAtMailCarrier))
diaryRepository.save<Diary>(extendedDiary)
or I could save the entry and call a specific custom query to add a relationship between the diary and the entry
val savedEntry= entryRepository.save(entryJan03ChaseSquirrel)
diaryRepository.addEntryToDiary(diaryId = diaryId, entryId = savedEntry.id!!)
@Repository
interface DiaryRepository : Neo4jRepository<Diary, Long> {
@Query(
value = "MATCH (d:Diary) " +
"WHERE id(d)=\$diaryId " +
"WITH d " +
"MATCH (e:Entry) " +
"WHERE id(e)=\$entryId " +
"CREATE (d)-[:DIARY_TO_ENTRY]->(e) "
)
fun addEntryToDiary(
@Param("diaryId") diaryId: Long, @Param("entryId") entryId: Long
)
}
Even though my lifespan is somewhat shorter than that of my human companions, I would imagine that the latter strategy would be more efficient, as the diary got longer.
So, is there an alternative strategy here that I have not considered, either some spring data approach or a more effective custom cypher query ?
Any ideas gratefully accepted.
Solved! Go to Solution.
03-02-2021 01:48 AM
+1 to the custom query, this will be more efficient as entries grow in size.
03-02-2021 01:48 AM
+1 to the custom query, this will be more efficient as entries grow in size.
03-02-2021 01:45 PM
Thanks for the feedback - I will stay with this approach then.
All the sessions of the conference are now available online