Realm子查询从1个表和2个表中筛选数据

时间:2019-09-24 06:39:28

标签: ios swift xcode realm realm-mobile-platform

假设我在Realm数据库中有两个模型和对应的表

public class Customer :Object {
   dynamic var  Id : String = ""
   dynamic var  NAME : String = ""
   dynamic var  Address : String = ""

   override public class func primaryKey() -> String? {
      return "Id"
   }  
}


public class Bills :Object {
    dynamic var  Id : String = ""
    dynamic var  Amount : String = ""
    dynamic var  CustomerId : String = ""

    override public class func primaryKey() -> String? {
        return "Id"
    }
}
  

我在做什么:通过这样做,我很容易获得所有客户的列表   这个

realmObj.objects(Customer.self)
  

我想要的内容:我要执行以下操作。

我想获得所有“客户”列表,但我也希望列表中包含此类客户,他们经常购买商品。我的意思是,我希望根据从我们的商店购买更多时间的客户来订购商品。为此,我可以从“帐单”表中的客户ID中获取它。 但是我不知道如何在Realm中进行操作。

我知道可以通过子查询来完成,但是我没有在Realm中做到这一点。请在此处告诉我什么是查询/谓词,以获取所需的结果。

1 个答案:

答案 0 :(得分:1)

我有两个答案,但首先要解决几件事。

对于这两个类,如果希望它们由Realm管理,则需要在每个要管理的变量之前添加@objc

public class Customer :Object {
   @objc dynamic var  Id : String = ""

或在类名中添加@objcMembers

@objcMembers class Customer :Object {
       dynamic var  Id : String = ""

另一件事是,类属性(变量)应始终为小写,类名称应以大写开头。什么都不是全部CAPS。

public class Customer :Object {
   @objc dynamic var  customer_id : String = ""
   @objc dynamic var  name : String = ""

第一个解决方案是使用您当前的结构:

var topCustomers = [(String, Int)]() //stores the customer id and count in an array of tuples
let results = realm.objects(Bills.self) //get all the bills
let allCustomerIds = results.map{ $0.CustomerId } //get a list of all of the customer id's
let uniqueIds = Set(allCustomerIds) //create a set of unique customer ids

for custId in uniqueIds { //iterate over the array of unique customer id's
    let count = results.filter("CustomerId == %@", custId).count // get a count of each customer id from results
    topCustomers.append( (custId, count) ) //add the customer id and it's count to the array
}

topCustomers.sort { $0.1 > $1.1 } //sort the array by count
for x in topCustomers { //print out the array - the customer with the most bills will be at the top
    print(x.0, x.1)
}

第二种更优雅的方法是使用客户与其帐单之间的关系。这将为生成报告,查询和整个组织提供更多的灵活性。

这是更新的课程:

class CustomerClass: Object {
   @objc dynamic var  customer_id = UUID().uuidString
   @objc dynamic var  name = ""
   @objc dynamic var  address = ""

   let billList = List<BillClass>()

   override public class func primaryKey() -> String? {
      return "customer_id"
   }
}

class BillClass: Object {
    @objc dynamic var  bill_id = UUID().uuidString
    @objc dynamic var  amount = ""

    override public class func primaryKey() -> String? {
        return "bill_id"
    }
}

然后是很短的代码来完成与第一个示例中相同的操作

let customers = realm.objects(CustomerClass.self) //get all customers
let results = customers.map { ($0.name, $0.billList.count) } //iterate over all, creating tuple with customer name & bill count
let sortedResults = results.sorted(by: { $0.1 > $1.1} ) //sort by bill count, descending
sortedResults.forEach { print($0) } //print the results, customer will most bills at top

注意使用UUID()。uuidString

@objc dynamic var  bill_id = UUID().uuidString

为您的对象创建唯一的主键。消除了处理索引,唯一性,递增等问题。