如何查询和计算领域数据库中的条目
How Query and Count entries in a Realm Database
我想构建一个搜索,用户可以在其中逐步过滤结果。所以没有选择集,有一个按钮说例如“1,234,567 个结果”,例如,如果您选择一种颜色,结果集会缩小……我们都知道这种搜索。我确实构建了很多次,但这是 Realm 中的第一次(swift)。
假设我有 5 个人 Table,那么每个人大约有 145,224 个 Dog 条目,每个 Dog 大约有 2,507,327 个 Cat 条目。如何查询和计算 Realm 中的嵌套对象?
class Person: Object {
@objc dynamic var name = ""
let dogs = List<Dog>()
// ...other Properties
}
extension Person {
static func all(in realm: Realm = try! Realm()) -> Results<Person> {
return realm.objects(Person.self)
}
}
// counts -> 145,224 db entries per person
class Dog: Object {
@objc dynamic var name = ""
dynamic var Person: Person?
let cats = List<Cats>()
// ...other Properties as well
}
extension Dog {
static func all(in realm: Realm = try! Realm()) -> Results<Dog> {
return realm.objects(Dog.self)
}
}
// counts -> 2,507,327 db entries per dogs
class Cat: Object {
@objc dynamic var name = ""
dynamic var Cat: Cat?
}
extension Cat {
static func all(in realm: Realm = try! Realm()) -> Results<Cat> {
return realm.objects(Cat.self)
}
}
// Get the default Realm
let realm = try! Realm()
// Query Realm for all dogs
let dogs = Person.all(in: realm).flatMap { [=10=].dogs }
dogs.count // => takes ~20 seconds to count
换句话说,什么是最快的方法来获取(统计)所有 Persons 的所有 Dog 条目(暂时让猫放在一边)。
我试图通过将结果限制为 1000 来解决该问题。如果结果 >1000,则将按钮标记为“> 1000 个结果”。但即使它需要很长时间(我想无论如何都会得到所有计数)。
那我做错了什么?
他们计算计数的方式需要将所有 Dog
对象加载到内存中,这确实效率低下。这就是为什么你看到如此糟糕的表现。您想利用 Realm 的延迟加载功能。您可能需要阅读相关内容。
我会通过摆脱托管 Person
属性 并将其替换为 LinkingObjects 来更新您的 Dog
对象。如果您将 Dog
存储在 Person.dogs
列表中,那么 realm 将为您创建一个返回 link 到 Person
的列表。您可能想对 Cat
做同样的事情。这样您就可以设置一些非常强大的嵌套查询。
为方便起见,您可以添加计算的 Person
属性 以索引到 LinkingObjects
。请注意,您将无法在任何查询中使用 属性。
class Dog: Object {
@objc dynamic var name = ""
let persons = LinkingObjects(fromType: Person.self, property: "dogs")
var person: Person? { persons.first }
}
计算计数的一种方法是查询所有 Person
个对象并对每个 Person
.
的 dogs
的计数求和
let count = realm.objects(Person.self).reduce(0) { result, person in
return result + person.dogs.count
}
另一个选项是查询具有相应 Person
的 Dog
个对象。如果 Dog
不在 Person.dogs
列表中,则不会显示查询。
let realm = try! Realm()
let count = realm.objects(Dog.self).filter("persons.@count > 0").count
任何一个选项都会比您所拥有的更有效。
希望对您有所帮助。
我想构建一个搜索,用户可以在其中逐步过滤结果。所以没有选择集,有一个按钮说例如“1,234,567 个结果”,例如,如果您选择一种颜色,结果集会缩小……我们都知道这种搜索。我确实构建了很多次,但这是 Realm 中的第一次(swift)。
假设我有 5 个人 Table,那么每个人大约有 145,224 个 Dog 条目,每个 Dog 大约有 2,507,327 个 Cat 条目。如何查询和计算 Realm 中的嵌套对象?
class Person: Object {
@objc dynamic var name = ""
let dogs = List<Dog>()
// ...other Properties
}
extension Person {
static func all(in realm: Realm = try! Realm()) -> Results<Person> {
return realm.objects(Person.self)
}
}
// counts -> 145,224 db entries per person
class Dog: Object {
@objc dynamic var name = ""
dynamic var Person: Person?
let cats = List<Cats>()
// ...other Properties as well
}
extension Dog {
static func all(in realm: Realm = try! Realm()) -> Results<Dog> {
return realm.objects(Dog.self)
}
}
// counts -> 2,507,327 db entries per dogs
class Cat: Object {
@objc dynamic var name = ""
dynamic var Cat: Cat?
}
extension Cat {
static func all(in realm: Realm = try! Realm()) -> Results<Cat> {
return realm.objects(Cat.self)
}
}
// Get the default Realm
let realm = try! Realm()
// Query Realm for all dogs
let dogs = Person.all(in: realm).flatMap { [=10=].dogs }
dogs.count // => takes ~20 seconds to count
换句话说,什么是最快的方法来获取(统计)所有 Persons 的所有 Dog 条目(暂时让猫放在一边)。
我试图通过将结果限制为 1000 来解决该问题。如果结果 >1000,则将按钮标记为“> 1000 个结果”。但即使它需要很长时间(我想无论如何都会得到所有计数)。
那我做错了什么?
他们计算计数的方式需要将所有 Dog
对象加载到内存中,这确实效率低下。这就是为什么你看到如此糟糕的表现。您想利用 Realm 的延迟加载功能。您可能需要阅读相关内容。
我会通过摆脱托管 Person
属性 并将其替换为 LinkingObjects 来更新您的 Dog
对象。如果您将 Dog
存储在 Person.dogs
列表中,那么 realm 将为您创建一个返回 link 到 Person
的列表。您可能想对 Cat
做同样的事情。这样您就可以设置一些非常强大的嵌套查询。
为方便起见,您可以添加计算的 Person
属性 以索引到 LinkingObjects
。请注意,您将无法在任何查询中使用 属性。
class Dog: Object {
@objc dynamic var name = ""
let persons = LinkingObjects(fromType: Person.self, property: "dogs")
var person: Person? { persons.first }
}
计算计数的一种方法是查询所有 Person
个对象并对每个 Person
.
dogs
的计数求和
let count = realm.objects(Person.self).reduce(0) { result, person in
return result + person.dogs.count
}
另一个选项是查询具有相应 Person
的 Dog
个对象。如果 Dog
不在 Person.dogs
列表中,则不会显示查询。
let realm = try! Realm()
let count = realm.objects(Dog.self).filter("persons.@count > 0").count
任何一个选项都会比您所拥有的更有效。
希望对您有所帮助。