【问题标题】:Cursor based pagination search with sorting in MongoDB and include the null field基于光标的分页搜索,在 MongoDB 中进行排序并包含空字段
【发布时间】:2021-10-25 20:02:29
【问题描述】:

我尝试构建查询以执行基于光标的搜索并对某些字段进行排序。但是,如果有人按此字段排序,我无法获得某些具有空字段的数据的正确结果。

我的API接口应该是

// client can specify the size he wants to get and after is the ID of the last object he gets before
// response contains [totlaCount], [endCursor], [hasNextPage] information
searchUsers(groupId: ID!, size: Int = 10, after: String): Response

如果我在数据库中有这样的数据:

User A ("_id": "1", "name": "A")
User B ("_id": "2")
User C ("_id": "3", "name": "C")
User D ("_id": "4")
User E ("_id": "5", "name": "E")
User F ("_id": "6", "name": "F")

我需要按“名称”对它们进行排序,并返回结果如下:

First Query (size = 3)
User A ("_id": "1", "name": "A")
User C ("_id": "3", "name": "C")
User E ("_id": "5", "name": "E")

Second Query (size = 3, after = "5")
User A ("_id": "6", "name": "F")
User B ("_id": "2")
User D ("_id": "4")

这是我的查询:

let startFrom = {
  $match: {},
};
if (hasLastUser) {
  startFrom = {
    $match: {
      $or: [
        {
          name:
            sortOrder === SortOrder.ASCENDING
              ? { $gt: lastUser.name }
              : { $lt: lastUser.name },
        },
        {
          name: lastUser.name,
          _id: { $gt: after },
        },
      ],
    },
  };
}

const query = await this.userModel.aggregate([
  // Stage 1: Filter
  {
    $match: {
      $and: [
        {
          groups: {
            $elemMatch: {
              group: { $in: ids },
            },
          },
        },
        {
          $or: [
            { email: { $regex: regKeyword } },
            { name: { $regex: regKeyword } },
            { phone: { $regex: regKeyword } },
          ],
        },
      ],
    },
  },

  // Stage 2: Sorting
  {
    $sort: {
      name: sortOrder === SortOrder.ASCENDING ? 1 : -1, // 1 for ascending, -1 for descending,
      _id: 1,
    },
  },
  // Stage 3: Skip previous data
  startFrom,
  // Stage 4: Limit the size
  {
    $limit: size,
  },
]);

但是!!我发现在我的查询中找不到不包含“姓名”字段的用户:

First Query (size = 3)
User A ("_id": "1", "name": "A")
User C ("_id": "3", "name": "C")
User E ("_id": "5", "name": "E")

Second Query (size = 3, after = "5")
User A ("_id": "6", "name": "F")

我该如何解决这个问题?

【问题讨论】:

    标签: mongodb mongoose mongodb-query typegoose


    【解决方案1】:

    $match 阶段正在过滤掉没有姓名的用户。在 $or 中,只有名称与正则表达式匹配的文档才会返回,因此没有名称的文档将被过滤掉。

    Playground

    【讨论】:

    • 您好,这应该不是根本原因。因为我在第一阶段注释掉了正则表达式部分仍然得到相同的结果。问题是我在第一阶段确认包含名称为空的用户,因为当我将大小设置为 10 并且所有这些(包括名称为空的用户)都在结果中。
    猜你喜欢
    • 2020-02-17
    • 2021-06-27
    • 2014-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多