如何使用猫鼬根据光标查询页面(不使用跳过)?

时间:2019-03-02 03:24:06

标签: mongodb mongoose

在我的模型db.listing中,有两个字段updatelocation可排序:

db.listing.find().sort({ update: -1 }).limit(50);

db.listing.find({
  location: {
    $near: {
      $maxDistance: 10000,
      $geometry: {
        type: 'Point',
        coordinates
      }
    }
  }
}).limit(50);

通知用户可以转到第二页,因此他们可以返回end_cursor,即文档的objectId。

所以理想情况下,我喜欢做类似的事情:

db.listing.sort({ update: -1 }).cursor('_id').lt(end_cursor).limit(50);

db.listing.find({
  location: {
    $near: {
      $maxDistance: 10000,
      $geometry: {
        type: 'Point',
        coordinates
      }
    }
  }
}).cursor('_id').lt(end_cursor).limit(50);

是否具有与where相似的功能,但是它将_id用作光标而不是将其用作第二种?

当然,我可以使用skip,但它也需要我在查询中找到end_cursor的位置...

似乎猫鼬没有内置这种功能。所以这是我的解决方案:

const getSeenIdsByEndCursor = async ({
  seen_ids = [],
  end_cursor,
  cursor
}) => {
  if (!cursor.hasNext())
    return seen_ids;
  const doc = cursor.next();
  seen_ids.push(doc._id);
  if (end_cursor === doc._id)
    return seen_ids;
  return await getSeenIdsByEndCursor({
    seen_ids,
    end_cursor,
    cursor
  })
}

const listByDistance = async function({
  coordinates,
  distance,
  end_cursor
}) {
  if (!Array.isArray(coordinates)) {
    return;
  }
  if (!end_cursor) {
    return await db.listing.find({
      location: {
        $near: {
          $maxDistance: 10000,
          $geometry: {
            type: 'Point',
            coordinates
          }
        }
      }
    }).limit(50);
  }
  const cursor = db.listing.find({
    location: {
      $near: {
        $minDistance: distance,
        $maxDistance: 10000,
        $geometry: {
          type: 'Point',
          coordinates
        }
      }
    }
  }).limit(50);
  const seen_ids = await getSeenIdsByEndCursors({
    cursor,
    end_cursor
  });
  return await db.listing.find({
    location: {
      $near: {
        $minDistance: distance,
        $maxDistance: 10000,
        $geometry: {
          type: 'Point',
          coordinates
        }
      }
    }
  }).where('_id').nin(seen_ids).limit(50);
}

0 个答案:

没有答案