MongoDB 领域 - 过滤查询
MongoDB Realm - Filter Queries
在我将领域连接到 MongoDB 集合的方案部分中,有一个选项卡用于添加过滤器查询以过滤正在同步的结果。我添加了一个过滤器,但每次我在应用程序上查询以加载数据时,我都会得到所有文档而不是过滤后的文档。
如何过滤应用接收的数据?
集合架构:
{
"title": "Group",
"required": [
"_id",
"cDate",
"name",
"info",
"isPublic",
"joinWithRequest",
"partition"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"admins": {
"bsonType": "array",
"items": {
"bsonType": "objectId"
}
},
"members": {
"bsonType": "array",
"items": {
"bsonType": "objectId"
}
},
"photoItems": {
"bsonType": "array",
"items": {
"bsonType": "object",
"title": "Item",
"properties": {
"id": {
"type": "string"
},
"cDate": {
"bsonType": "date"
}
},
"required": [
"id",
"cDate"
]
}
},
"videoItems": {
"bsonType": "array",
"items": {
"bsonType": "object",
"title": "Item",
"properties": {
"id": {
"type": "string"
},
"cDate": {
"bsonType": "date"
}
},
"required": [
"id",
"cDate"
]
}
},
"cDate": {
"bsonType": "date"
},
"partition": {
"bsonType": "string"
},
"name": {
"bsonType": "string"
},
"info": {
"bsonType": "string"
},
"icon": {
"bsonType": "string"
},
"isPublic": {
"bsonType": "bool"
},
"joinWithRequest": {
"bsonType": "bool"
}
}
}
过滤器:
客户查询:
let groups = realm.objects(Group.self).sorted(byKeyPath: "cDate")
您所问的是(曾经)称为基于查询的同步。虽然它限制了数据同步量,但它也受到用户数量、系统资源等的限制。
At this time query based sync is no longer supported in MongoDB Realm
但是,您可以通过利用分区获得大部分相同的功能 - 分区无论如何都是同步所必需的。让我举一个高层次的例子。
假设您有一个包含用户的 'posts' 应用,然后 post 由特定组的用户完成。对于此示例,此用户属于 Group_0 和 Group_1。您的用户对象可能如下所示
class UserClass: Object {
@objc dynamic var _id: //a users uid
@objc dynamic var user_name = ""
let groupPartitionList = List<GroupClass>() //will populate with Group_0 and Group_1
}
和 post 可能看起来像这样
class PostClass: Object {
@objc dynamic var _id: ObjectId = ObjectId.generate()
@objc dynamic var _partitionKey: GroupPartition = ""
@objc dynamic var title = ""
@obcj dynamic var post = ""
override static func primaryKey() -> String? {
return "_id"
}
}
假设有 50 个不同的组。
在用户验证和用户对象填充后,您就会知道用户属于 Group_0 和 Group_1,这可以显示在弹出菜单中 - 默认为第一组,Group_0.
用户登录后,仅获取 Group_0 posts
let whichPartition = myUserObject.groupPartitionList[0] //object at index 0 = Group_0
let config = user.configuration(partitionValue: whichPartition)
Realm.asyncOpen(configuration: config) { result in
...
let group0Posts = realm.objects(PostClass.self) //loads just the posts Group_0
}
如您所见,没有查询:数据受分区键限制,例如,这不会从任何其他组读取 posts - 只有 posts 具有分区键Group_0
同样,如果用户将弹出窗口更改为 Group_1,则只有分区键为 Group_1 的 post 会同步,而不会同步其他。因此,即使有 50 个组和数千个 post,您也只能通过分区值下载和同步 Group_0 和 Group_1。
您可以通过使用服务器过滤器(如问题的评论中所述)来进一步增强此功能以保留某些数据,以便在服务器级别查询的数据量更小。
例如,您可以添加一个过滤器以忽略任何超过 5 年的 post。这将通过减少被查询的数据量来显着加快查询速度(这实际上可以减少结果的数量,因为那些被忽略了)
MongoDB 领域文档 Partition Atlas Data Into Realms 中有一些优秀的读物。
在我将领域连接到 MongoDB 集合的方案部分中,有一个选项卡用于添加过滤器查询以过滤正在同步的结果。我添加了一个过滤器,但每次我在应用程序上查询以加载数据时,我都会得到所有文档而不是过滤后的文档。 如何过滤应用接收的数据?
集合架构:
{
"title": "Group",
"required": [
"_id",
"cDate",
"name",
"info",
"isPublic",
"joinWithRequest",
"partition"
],
"properties": {
"_id": {
"bsonType": "objectId"
},
"admins": {
"bsonType": "array",
"items": {
"bsonType": "objectId"
}
},
"members": {
"bsonType": "array",
"items": {
"bsonType": "objectId"
}
},
"photoItems": {
"bsonType": "array",
"items": {
"bsonType": "object",
"title": "Item",
"properties": {
"id": {
"type": "string"
},
"cDate": {
"bsonType": "date"
}
},
"required": [
"id",
"cDate"
]
}
},
"videoItems": {
"bsonType": "array",
"items": {
"bsonType": "object",
"title": "Item",
"properties": {
"id": {
"type": "string"
},
"cDate": {
"bsonType": "date"
}
},
"required": [
"id",
"cDate"
]
}
},
"cDate": {
"bsonType": "date"
},
"partition": {
"bsonType": "string"
},
"name": {
"bsonType": "string"
},
"info": {
"bsonType": "string"
},
"icon": {
"bsonType": "string"
},
"isPublic": {
"bsonType": "bool"
},
"joinWithRequest": {
"bsonType": "bool"
}
}
}
过滤器:
客户查询:
let groups = realm.objects(Group.self).sorted(byKeyPath: "cDate")
您所问的是(曾经)称为基于查询的同步。虽然它限制了数据同步量,但它也受到用户数量、系统资源等的限制。
At this time query based sync is no longer supported in MongoDB Realm
但是,您可以通过利用分区获得大部分相同的功能 - 分区无论如何都是同步所必需的。让我举一个高层次的例子。
假设您有一个包含用户的 'posts' 应用,然后 post 由特定组的用户完成。对于此示例,此用户属于 Group_0 和 Group_1。您的用户对象可能如下所示
class UserClass: Object {
@objc dynamic var _id: //a users uid
@objc dynamic var user_name = ""
let groupPartitionList = List<GroupClass>() //will populate with Group_0 and Group_1
}
和 post 可能看起来像这样
class PostClass: Object {
@objc dynamic var _id: ObjectId = ObjectId.generate()
@objc dynamic var _partitionKey: GroupPartition = ""
@objc dynamic var title = ""
@obcj dynamic var post = ""
override static func primaryKey() -> String? {
return "_id"
}
}
假设有 50 个不同的组。
在用户验证和用户对象填充后,您就会知道用户属于 Group_0 和 Group_1,这可以显示在弹出菜单中 - 默认为第一组,Group_0.
用户登录后,仅获取 Group_0 posts
let whichPartition = myUserObject.groupPartitionList[0] //object at index 0 = Group_0
let config = user.configuration(partitionValue: whichPartition)
Realm.asyncOpen(configuration: config) { result in
...
let group0Posts = realm.objects(PostClass.self) //loads just the posts Group_0
}
如您所见,没有查询:数据受分区键限制,例如,这不会从任何其他组读取 posts - 只有 posts 具有分区键Group_0
同样,如果用户将弹出窗口更改为 Group_1,则只有分区键为 Group_1 的 post 会同步,而不会同步其他。因此,即使有 50 个组和数千个 post,您也只能通过分区值下载和同步 Group_0 和 Group_1。
您可以通过使用服务器过滤器(如问题的评论中所述)来进一步增强此功能以保留某些数据,以便在服务器级别查询的数据量更小。
例如,您可以添加一个过滤器以忽略任何超过 5 年的 post。这将通过减少被查询的数据量来显着加快查询速度(这实际上可以减少结果的数量,因为那些被忽略了)
MongoDB 领域文档 Partition Atlas Data Into Realms 中有一些优秀的读物。