Realm Swift select 匹配一对多关系实体中一个字段的所有值

Realm Swift select all values which match one field in one-to-many relationship entity

我在领域 Product 和 ProductType 中有两个实体。产品与产品类型具有一对多关系。

产品实体一对多

import Foundation
import RealmSwift

class Product: Object{
    dynamic var productName = ""
    let productTypeList = List<ProductType>() 
}

ProductType 实体

import Foundation
import RealmSwift

class ProductType: Object{   
  dynamic var typeName: String = ""
  dynamic var typeLogoUrl: String = ""
}

我的目标是 select 所有产品,其中包含 ProductType typeName,例如 "Electronics"。如果有这样的一对一关系,我可以轻松做到

产品实体一对一

import Foundation
import RealmSwift

class Product:Object{
    dynamic var productName = ""
    dynamic var productType : ProductType? 
}

查询示例

let realm = try! Realm()
let productTypeName = "Electronics"
let predicate = NSPredicate(format: "productType.typeName == %@", productTypeName)
let rmProducts = realm.objects(Product.self).filter(predicate)

关于如何使用产品的一对多版本进行查询的任何想法 class?

您可以使用子查询并检查列表中与名称匹配的 productTypes 的计数是否大于 0。

let rmProducts = realm.objects(Product.self).filter("SUBQUERY(productTypeList, $type, $type.typeName == %@).@count>0",productTypeName)

我运行查询了以下测试集并得到了预期的结果:

class Product:Object{
    dynamic var productName = ""
    var productTypeList = List<ProductType>()
}

class ProductType  : Object{
    dynamic var typeName: String = ""
    dynamic var typeLogoUrl: String = ""
}

let types = [ProductType(value: ["typeName":"Electronics","typeLogoUrl":"url"]),ProductType(value: ["typeName":"a","typeLogoUrl":"url"]),ProductType(value: ["typeName":"Electronics","typeLogoUrl":"a"]),ProductType(value: ["typeName":"b","typeLogoUrl":"url"])]

let prod1 = Product()
prod1.productName = "a"
prod1.productTypeList = List([types[0],types[1]])
let prod2 = Product()
prod2.productName = "b"
prod2.productTypeList = List([types[3],types[1]])
let prod3 = Product()
prod3.productName = "c"
prod3.productTypeList = List([types[2],types[1]])
var prod4 = Product()
prod4.productName = "d"
prod4.productTypeList = List([types[1]])

try! realm.write {
    realm.add(types)
    realm.add([prod1,prod2,prod3,prod4])
}

let productTypeName = "Electronics"
let predicate = NSPredicate(format: "productType.typeName == %@", productTypeName)
let rmProducts = realm.objects(Product.self).filter("SUBQUERY(productTypeList, $type, $type.typeName == %@).@count>0",productTypeName)
print(rmProducts) //rmProducts contains prod1 and prod3 as expected

对于像这样的简单查询,您需要 ANY 修饰符:

realm.objects(Product.self).filter("ANY productTypeList.typeName == %@", productTypeName)

A SUBQUERY,如另一个答案中所建议的,只有在每个子对象上需要多个条件才能匹配时才有必要。例如,如果您想查找 Products 具有给定类型的项目,其 URL 以 https:// 开头,您将使用 SUBQUERY:

realm.objects(Product.self).filter("SUBQUERY(productTypeList, $type, $type.typeName == %@ AND $type.typeLogoUrl BEGINSWITH 'https://').@count > 0", productTypeName)