Hi Everybody
I’ve a database composed by 3 entity:
Headword, Writing and Meaning
Relationship is one-to-many: One headword has many Writing and many Meaning.
Following the tutorial of Andrew Tetlaw @atetlaw about core data, I’ve used the nsbatchinserrequest to download the json, decoding and insert the objects in db.
making only the inserting all database composed by about 22000 records (I have 7300 headword, 7600 Meanings and 7400 Writings) is inserted in db in only 3 seconds. Very fast!!! but if after execution of batch insert request I try to set the relationship, all operation is done in 40 seconds.
I know that (and Andrew Tetlaw says so explicitly) with NSBatchInsertRequest you can’t set relationship. in fact, it throw an exception that it says that the objects are in different context.
But there is a fast way to manage the relationship?
This is the code that I’m using to do the insertion:
private func importJaappDB(from jaappJSON:JaappJSON) throws {
guard let radicali = jaappJSON.radicali else { return }
guard let kanji = jaappJSON.kanji else { return }
guard let kunYomi = jaappJSON.kunYomi else { return }
guard let onYomi = jaappJSON.onYomi else { return }
guard let lemmi = jaappJSON.lemmi else { return }
guard let scritture = jaappJSON.lemmaScrittura else { return }
guard let significati = jaappJSON.lemmaSignificato else { return }
var performError: Error?
let taskContext = appDelegate.newTaskContext()
taskContext.performAndWait {
let radicalsBatchInsert = self.newBatchInsertRadicaliRequest(with: radicali)
radicalsBatchInsert.resultType = .statusOnly
let kanjiBatchInsert = self.newBatchInsertKanjiRequest(with: kanji)
kanjiBatchInsert.resultType = .statusOnly
let kunYomiBatchInsert = self.newBatchInsertKunYomiRequest(with: kunYomi)
kunYomiBatchInsert.resultType = .statusOnly
let onYomiBatchInsert = self.newBatchInsertOnYomiRequest(with: onYomi)
onYomiBatchInsert.resultType = .statusOnly
let lemmaBatchInsert = self.newBatchInsertLemmaRequest(with: lemmi)
lemmaBatchInsert.resultType = .statusOnly
let scritturaBatchInsert = self.newBatchInsertScritturaRequest(with: scritture)
scritturaBatchInsert.resultType = .statusOnly
let significatoBatchInsert = self.newBatchInsertSignificatoRequest(with: significati)
significatoBatchInsert.resultType = .statusOnly
do {
let batchRadicalInsertResult = try taskContext.execute(radicalsBatchInsert) as? NSBatchInsertResult
let batchInsertResult = try taskContext.execute(kanjiBatchInsert) as? NSBatchInsertResult
let batchKunYomiInsertResult = try taskContext.execute(kunYomiBatchInsert) as? NSBatchInsertResult
let batchOnYomiInsertResult = try taskContext.execute(onYomiBatchInsert) as? NSBatchInsertResult
let batchLemmaInsertResult = try taskContext.execute(lemmaBatchInsert) as? NSBatchInsertResult
let batchScritturaInsertResult = try taskContext.execute(scritturaBatchInsert) as? NSBatchInsertResult
let batchSignificatoInsertResult = try taskContext.execute(significatoBatchInsert) as? NSBatchInsertResult
let radicaliList = getRadicali()
let kanjiList = getKanji()
let kunYomiList = getKunYomi()
let onYomiList = getOnYomi()
let headwordList = getlemmi()
let scritture = getScritture()
let significati = getSignificati()
for radicale in radicaliList {
let kanjiRelazione = kanjiList.filter{($0.radicale?.contains(radicale.radicale!))!}
radicale.addToKanji(NSSet(array: kanjiRelazione))
}
_ = kanjiList.map{$0.addToLettureKun(NSSet(array: kunYomiList.filter{($0.idKanji == $0.id)}))}
_ = kanjiList.map{$0.addToLettureOn(NSSet(array: onYomiList.filter{($0.idKanji == $0.id)}))}
// for kanji in kanjiList {
// let kunYomiRelationship = kunYomiList.filter{($0.idKanji == kanji.id)}
// let onYomiRelationship = onYomiList.filter{($0.idKanji == kanji.id)}
// kanji.addToLettureKun(NSSet(array: kunYomiRelationship))
// kanji.addToLettureOn(NSSet(array: onYomiRelationship))
// }
_ = lemmaList.map{ $0.addToScrittura(NSSet(array: scritture.filter{($0.idLemma == $0.id)}))}
_ = lemmaList.map{ $0.addToSignificato(NSSet(array: significati.filter{($0.idLemma == $0.id)}))}
// for lemma in lemmaList {
// let scrittureRelationship = scritture.filter{($0.idLemma == lemma.id)}
// let significatiRelationship = significati.filter{($0.idLemma == lemma.id)}
// lemma.addToScrittura(NSSet(array: scrittureRelationship))
// lemma.addToSignificato(NSSet(array: significatiRelationship))
// }
if let successRadical = batchRadicalInsertResult?.result as? Bool,
let successKanji = batchInsertResult?.result as? Bool,
let successKunYomi = batchKunYomiInsertResult?.result as? Bool,
let successOnYomi = batchOnYomiInsertResult?.result as? Bool,
let successLemmi = batchLemmaInsertResult?.result as? Bool,
let successScritture = batchScritturaInsertResult?.result as? Bool,
let successSignificati = batchSignificatoInsertResult?.result as? Bool,
successRadical, successKanji, successKunYomi, successOnYomi, successLemmi, successScritture, successSignificati {
try taskContext.save()
DispatchQueue.main.async {
print("numero di radicali:\(self.getRadicali().count)")
print("numero di Kanji:\(self.getKanji().count)")
print("numero di KunYomi:\(self.getKunYomi().count)")
print("numero di OnYomi:\(self.getOnYomi().count)")
print("numero di Lemmi:\(self.getlemmi().count)")
}
}
return
} catch {
performError = JaappError.batchInsertError
}
performError = JaappError.batchInsertError
}
if let error = performError {
throw error
}
}
if there is something you don’t understand, just ask.
thank you