1

我有两个模型 -

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

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

我一直在使用insertOrUpdate()更新 Route 类,假设当我调用它时,directionList 中的现有方向对象被删除并替换为我提供的新列表。然而,我最近发现这并没有发生。当我调用时,甚至不支持级联删除route.deleteFromRealm()。所以现在我在 Direction 表中有数百个对象,没有对象引用它们。

如何从 Direction 类中删除所有在 Realm 迁移中没有引用它们的 Route 对象的对象?

4

3 回答 3

2

我能想到的两种可能的方法。

目前第一个可能对您没有帮助,但将来可能会。通过向Direction类添加 LinkingObjects 属性,您可以让模型确定哪些Direction对象没有相关Route对象。此处描述了 LinkingObjects ( https://realm.io/docs/java/5.8.0/api/io/realm/annotations/LinkingObjects.html )。有一个属性Direction:例如:

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

然后,您可以删除以下任何对象:

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

不过,您可能需要为下一个版本执行此操作。

第二种方法更冗长,但本质上是:

  1. 查找所有Direction对象:RealmResults<Direction> redundantDirections = realm.where(Direction.class).findAll();
  2. 查找所有Route对象(类似于上面)。
  3. 遍历所有Route对象。
  4. 过滤redundantDirections查询以排除每个Direction对象引用的任何Route对象。
  5. 删除最后的redundantDirections.

我希望有第三种我不知道的方式......

于 2019-03-18T22:16:47.737 回答
1

这是我解决它的方式 -

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
    }
}

我发现了更多的东西。根据这个关于 Realm 的内容非常丰富的演讲 - https://academy.realm.io/posts/jp-simard-realm-core-database-engine/(跳到 28:45),有办法删除所有那些未引用的节点来自 B 树。但是,我找不到这样做的方法。Realm.compactRealm()似乎是一种方法,但没有奏效。

于 2019-03-19T09:53:23.907 回答
0

如何从 Direction 类中删除所有在 Realm 迁移中没有引用它们的 Route 对象的对象?

应该很容易使用DynamicRealmObject.linkingObjects

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

这在理论上应该有效

于 2019-03-28T14:20:32.160 回答