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 中有一些优秀的读物。