简体   繁体   English

通过快速将对象与NSPredicate数组中的对象的键路径进行比较来过滤多对多关系

[英]Filtering many-to-many relation by comparing objects agains keypath of objects in array with NSPredicate in swift

I hope you can help me. 我希望你能帮助我。 I'm building a Mac OS X App using Realm as the underlaying database system. 我正在使用Realm作为底层数据库系统来构建Mac OS X App。

My model looks like this: 我的模型如下所示:

-Brick: a text brick consisting of the properties title and text -砖:由属性标题和文本组成的文本砖

-GeneratorBrick: a many-to-many relation object for modeling the relation between Generator, Brick and some other data which is not relevant to the problem. -GeneratorBrick:多对多关系对象,用于对Generator,Brick和其他与问题无关的数据之间的关系进行建模。 Property on this object is called "brick" 该对象的属性称为“砖”

-Generator: a configuration consisting of some text as well as a list of GeneratorBricks whose property name is "generatorBricks" -Generator:由一些文本以及属性名称为“ generatorBricks”的GeneratorBrick列表组成的配置

In my App, I now have a Generator object. 在我的应用程序中,我现在有了一个Generator对象。 This one holds a list to a bunch of GeneratorBrick objects which themselves each have a Brick and some other data. 这个拥有一系列GeneratorBrick对象的列表,每个对象本身都有一个Brick和一些其他数据。 I display them in a TableView. 我将它们显示在TableView中。 I now want to display another TableView in which I only show those Brick objects which are not in the TableView of the current Generator. 现在,我想显示另一个TableView,其中仅显示那些不在当前Generator的TableView中的Brick对象。 Bricks in the generator i access by generator.generatorBricks[index].brick 我通过generator.generatorBricks[index].brick访问generator.generatorBricks[index].brick

In an earlier version of my App I loaded all the Brick objects I needed via var bricks: Results<Brick> = try! Realm().objects(Brick).sorted("title").filter("inGenerator = false") 在我的应用程序的早期版本中,我通过var bricks: Results<Brick> = try! Realm().objects(Brick).sorted("title").filter("inGenerator = false")加载了我需要的所有Brick对象var bricks: Results<Brick> = try! Realm().objects(Brick).sorted("title").filter("inGenerator = false") var bricks: Results<Brick> = try! Realm().objects(Brick).sorted("title").filter("inGenerator = false") but since my model changed from using a property "inGenerator" to using another model class "GeneratorBrick" I need another way to filter. var bricks: Results<Brick> = try! Realm().objects(Brick).sorted("title").filter("inGenerator = false")但是由于我的模型从使用属性“ inGenerator”更改为使用另一个模型类“ GeneratorBrick”,因此我需要另一种过滤方法。 Unfortunately I have no idea how to accomplish this task. 不幸的是,我不知道如何完成这项任务。 I tried different predicates like generatorBricks IN %@", generator.generatorBricks where the property "generatorBricks" is a backlink property in the Brick class. 我尝试了其他谓词,例如generatorBricks IN %@", generator.generatorBricks ,其中属性” generatorBricks“是Brick类中的反向链接属性。

Maybe I'm trying something which cannot be accomplished by using a predicate or maybe I just have not enough experience with predicates. 也许我正在尝试使用谓词无法完成的事情,或者我只是对谓词没有足够的经验。 Maybe I'm blind because I'm more used to plain SQL where I would use something like the following: 也许我是盲目的,因为我更习惯于使用简单的SQL,例如:

create table brick (
  id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  title varchar(255)
);
create table generator (
  id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  title varchar(255)
);

create table generatorbrick (
  id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
  brickId INT(6),
  generatorId INT(6)
) 

select * from brick b join generatorbrick gb on b.id = gb.brickid where gb.generatorid is not 123

Do you understandy my problem? 你了解我的问题吗? Do you need additional information? 您是否需要其他信息? I'm glad to provide if you can give me a hint into the right direction. 如果您能向我提示正确的方向,我很高兴提供。 Thank you in advance. 先感谢您。

What you would do in traditional SQL with (expensive) join operations, you should do in Realm with (cheap) graph relationships: 在具有(昂贵)联接操作的传统SQL中将执行的操作,应在具有(廉价)图关系的Realm中执行以下操作:

class Brick: Object {
  dynamic var title = ""
}
class BrickGenerator: Object {
  dynamic var id = 0
  dynamic var title = ""
  dynamic var brick: Brick? = nil
}

let realm = try! Realm()
let brick = realm.objects(BrickGenerator).filter("id != 123").first?.brick

I'm not 100% sure if this is the operation you're attempting to model, and I'm under the impression that these models could be simplified even more if I truly understood what you were trying to accomplish. 我不是100%知道这是否是您要建模的操作,而且我的印象是,如果我真正了解您要完成的工作,则可以进一步简化这些模型。

But the gist is that Realm is a graph database (not relational), so links are represented natively. 但要点是,Realm是一个图形数据库(不是关系数据库),因此链接以本机表示。 Try to think of what your models would look like if they were 100% in-memory, plain old Swift objects (classes/structs). 试想一下,如果模型是100%内存中的普通旧Swift对象(类/结构),它们将是什么样。

I came to the conclusion that what I want to do is not simply achievable with graph based Realm. 我得出的结论是,我想做的事不能简单地通过基于图的领域来实现。 At least not without loading all the bricks, generatorbricks and the generator and do a manually comparison by iterating over all the bricks and check if they are part of the current generator. 至少并非没有加载所有砖,发电砖和发电机,并通过迭代所有砖并检查它们是否为当前发电机的一部分来进行手动比较。

I would have needed something like 我本来需要

SELECT brick.* FROM brick JOIN generatorbrick on brick.id = generatorbrick.brickId JOIN generator on generator.id = generatorbrick.generatorId WHERE generator.id != 123

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM