从 1 table w.r.t table 2 过滤数据的领域子查询
Realm Subquery to filter data from 1 table w.r.t table 2
假设我在 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"
}
}
What I am doing: I am getting list of All customers easily by doing
this
realmObj.objects(Customer.self)
What I want: I want to do followings.
我想获取所有客户列表,但我还希望该列表包含最常购买商品的客户。我的意思是我希望根据从我们商店购买更多时间的客户来订购清单。为此,我可以从 Bills 表中的客户 ID 中获取它。
但是我不知道如何在Realm中做到这一点。
我知道可以通过子查询来完成,但我不知道如何在 Realm 中进行。请告诉我这里 query/Predicate 是什么以获得所需的结果。
我有两个答案,但有几件事需要先解决。
对于你的两个 classes,如果你希望它们由 Realm 管理,你需要在每个你想要管理的变量之前包含 @objc
public class Customer :Object {
@objc dynamic var Id : String = ""
或选择性地将@objcMembers 添加到 class 名称
@objcMembers class Customer :Object {
dynamic var Id : String = ""
另一件事是 class 属性 (vars) 应始终为小写,class 名称应以大写开头。什么都不应该全部大写。
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{ [=13=].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 { [=13=].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)
}
第二种更优雅的方法使用客户与其账单之间的关系。这将为生成报告、查询和整体组织提供更大的灵活性。
这是更新后的 classes:
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 { ([=15=].name, [=15=].billList.count) } //iterate over all, creating tuple with customer name & bill count
let sortedResults = results.sorted(by: { [=15=].1 > .1} ) //sort by bill count, descending
sortedResults.forEach { print([=15=]) } //print the results, customer will most bills at top
注意UUID().uuidString的使用
@objc dynamic var bill_id = UUID().uuidString
为您的对象创建唯一的主键。消除处理索引、唯一性、递增等。
假设我在 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"
}
}
What I am doing: I am getting list of All customers easily by doing this
realmObj.objects(Customer.self)
What I want: I want to do followings.
我想获取所有客户列表,但我还希望该列表包含最常购买商品的客户。我的意思是我希望根据从我们商店购买更多时间的客户来订购清单。为此,我可以从 Bills 表中的客户 ID 中获取它。 但是我不知道如何在Realm中做到这一点。
我知道可以通过子查询来完成,但我不知道如何在 Realm 中进行。请告诉我这里 query/Predicate 是什么以获得所需的结果。
我有两个答案,但有几件事需要先解决。
对于你的两个 classes,如果你希望它们由 Realm 管理,你需要在每个你想要管理的变量之前包含 @objc
public class Customer :Object {
@objc dynamic var Id : String = ""
或选择性地将@objcMembers 添加到 class 名称
@objcMembers class Customer :Object {
dynamic var Id : String = ""
另一件事是 class 属性 (vars) 应始终为小写,class 名称应以大写开头。什么都不应该全部大写。
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{ [=13=].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 { [=13=].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)
}
第二种更优雅的方法使用客户与其账单之间的关系。这将为生成报告、查询和整体组织提供更大的灵活性。
这是更新后的 classes:
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 { ([=15=].name, [=15=].billList.count) } //iterate over all, creating tuple with customer name & bill count
let sortedResults = results.sorted(by: { [=15=].1 > .1} ) //sort by bill count, descending
sortedResults.forEach { print([=15=]) } //print the results, customer will most bills at top
注意UUID().uuidString的使用
@objc dynamic var bill_id = UUID().uuidString
为您的对象创建唯一的主键。消除处理索引、唯一性、递增等。