假设我在领域数据库中有两个模型和相应的表
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中进行操作。请在此处告诉我什么是查询/谓词,以获取所需的结果。
我有两个答案,但首先要解决两件事。
对于这两个类,如果要它们由Realm管理,则需要在要管理的每个var之前包含@objc。>
public class Customer :Object { @objc dynamic var Id : String = ""
或可选地将@objcMembers添加到类名
@objcMembers class Customer :Object { dynamic var Id : String = ""
另一件事是,类属性(vars)应始终为小写,类名称应以大写开头。什么都不是全部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
为您的对象创建唯一的主键。消除了处理索引,唯一性,递增等的问题。