1
votes

Comment supprimer des objets Realm qui ne sont référencés par aucun autre objet lors de la migration?

J'ai deux modèles -

class Direction : RealmObject {
    var distance : Int
    var polyline : String
}

class Route  : RealmObject {
    var id : String
    var directionList : RealmList<Direction>
}

J'utilise insertOrUpdate () pour mettre à jour la classe Route en supposant que lorsque je l'appelle, les objets de direction existants in directionList ont été supprimés et remplacés par la nouvelle liste que j'ai fournie. Cependant, j'ai récemment découvert que cela ne se produisait pas. Même la suppression en cascade n'est pas prise en charge lorsque j'appelle route.deleteFromRealm () . Alors maintenant, je me suis retrouvé avec des centaines d'objets dans la table de direction sans aucun objet s'y référant.

Comment puis-je supprimer tous les objets de la classe Direction qui n'ont aucun objet Route qui leur fait référence dans la migration de Realm?


0 commentaires

3 Réponses :


2
votes

Je peux penser à deux façons possibles.

La première ne vous aidera peut-être pas pour le moment, mais elle le pourra peut-être à l'avenir. En ajoutant une propriété LinkingObjects à la classe Direction , vous pouvez laisser le modèle déterminer quels objets Direction n'ont aucun objet Route associé. LinkingObjects est décrit ici ( https: // realm .io / docs / java / 5.8.0 / api / io / realm / annotations / LinkingObjects.html ). Avec une propriété sur Direction : Par exemple:

RealmResults<Direction> unusedDirections = realm.where(Direction.class).isEmpty("routes").findAll();

Ensuite, vous pouvez supprimer tous les objets où:

\@LinkingObjects("direction")
final RealmResults<Route> routes = null;

Vous devrez peut-être le faire pour votre prochaine version.

Une deuxième voie est plus longue, mais essentiellement:

  1. Rechercher tous les objets Direction : RealmResults redundantDirections = realm.where (Direction.class) .findAll ();
  2. Trouvez tous les objets Route (similaire à ci-dessus).
  3. Parcourez tous les objets Route .
  4. Filtrez la requête redundantDirections pour exclure tous les objets Direction référencés par chaque objet Route .
  5. Supprimez les redondantesDirections finales.

J'espère qu'il y a un troisième moyen que je ne connais pas .....


3 commentaires

Hey @ chris-shaw, merci pour votre réponse. J'ai un doute supplémentaire. Existe-t-il un moyen d'ajouter ces objets de liaison dans la migration elle-même? Si tel est le cas, je peux peut-être ajouter cela d'abord, puis supprimer ceux qui ne sont pas liés. Cependant, en dehors de ce cas d'utilisation, je n'ai pas d'autre besoin des objets de liaison et semble redondant pour mon cas d'utilisation. J'ai résolu mon problème d'une manière quelque peu brute mais fonctionnelle, un peu similaire à celle que vous avez mentionnée dans votre deuxième manière.


@abhiank Pas que je sache. Vous pouvez essayer de poser une autre question spécifiquement à ce sujet au cas où quelqu'un le saurait.


DynamicRealmObject a en fait une méthode bindingObjects , ce qui a été une surprise pour moi aussi.



1
votes

Voici comment je l'ai résolu -

override fun migrate(realm: DynamicRealm, oldVersion1: Long, newVersion: Long) {

    if (oldVersion == 2L) {

        val routeSchema = schema.get("Route")
        val directionSchema = schema.get("Direction")

        /*
        Creating a new temp field called isLinked which is set to true for those which are
        references by Route objects. Rest of them are set to false. Then removing all
        those which are false and hence duplicate and unnecessary. Then removing the temp field
        isLinked
         */
        directionSchema!!
                .addField("isLinked", Boolean::class.java)
                .transform { obj ->
                    //Setting to false for all by default
                    obj.set("isLinked", false)
                }

        routeSchema!!.transform { obj ->
            obj.getList("directionList").forEach {
                //Setting to true for those which are referenced
                it.set("isLinked", true)
            }
        }

        //Removing all those which are set as false
        realm.where("Direction")
                .equalTo("isLinked", false)
                .findAll()?.deleteAllFromRealm()

        directionSchema.removeField("isLinked")

        //Rest of the migration
    }
}

Il y a d'autres choses que j'ai découvertes. Selon cette conférence très informative sur le royaume - https: // academy.realm.io/posts/jp-simard-realm-core-database-engine/ (passez à 28:45), il existe un moyen de supprimer tous ces nœuds non référencés de l'arbre B. Cependant, je n'ai pas pu trouver un moyen de le faire. Realm.compactRealm () semblait être un moyen de le faire, mais cela n'a pas fonctionné.


0 commentaires

0
votes

Comment puis-je supprimer tous les objets de la classe Direction qui n'ont aucun objet Route qui leur fait référence dans la migration de Realm?

Cela devrait être facile en utilisant DynamicRealmObject.linkingObjects.

val routes = realm.where("Destination").findAll()
routes.createSnapshot().forEach { route ->
    val linkingObjects = route.linkingObjects("Route", "directionList")
    if(linkingObjects.isEmpty()) {
        route.deleteFromRealm()
    }
}

Cela devrait théoriquement fonctionner


0 commentaires