1

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

我的 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")

我该如何解决这个查询?

4

1 回答 1

0

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

操场

于 2021-08-25T22:07:55.027 回答