使用相同的更新时间戳对MongoDB文档进行排序?

时间:2017-03-03 10:43:31

标签: javascript mongodb mongoose

我想在Express服务器中使用Supertest测试路由。在该路线上,我将获得MongoDB的数据列表,并且数据按updatedAt字段排序。

我想测试输出中的顺序是否正确,但是我有一个问题 - 似乎mongoDb速度太快,以至于某些文档具有相同的时间戳(没有认为这是可能的)。

enter image description here

这是如何在内部排序的?它似乎也没有被_id排序。以下是我的测试中生成文档的函数:

let first;
let last;
Array.from(Array(14)).forEach((e, i) => {
  const immo = new Immo({ user: this.user.model });
  immo.save();
  if (i === 2) {
    // last means last with limit 12 sorted by timestamps descending
    last = immo._id.toString();
  }
  if (i === 13) {
    // the last that was put in will be the first in the sorted list
    first = immo._id.toString();
  }
});

输出是用户编辑的最后12个项目。我保存了第一个和最后一个,所以我可以在测试中稍后断言它们。

但测试失败是因为有3个或4个具有相同的时间戳,并且实际上是最后一个按照我将它放入数据库的顺序而不是真正的最后一个Mongo按时间戳对其进行排序(或者首先在降序)。

我尝试在输入循环中通过for循环进行延迟,但这没有做任何事情。 (我可能不会使用Array.forEach吗?)

有什么方法可以确保文件之间至少有几个MS延迟?

1 个答案:

答案 0 :(得分:0)

原来我的问题是我没有考虑所有过程的异步性质。

我把所有东西都包裹在Promises中,它现在有效。这是我的新代码:

it('should return a list of the last 12 objects if a user has 14 objects', function (done) {
    let first;
    let last;
    let i = 0;
    const model = this.user.model;
    (function recur() {
      i += 1;
      return new Immo({ user: model })
        .save()
        .then((result) => {
          if (i === 3) {
            last = result._id.toString();
          } else if (i === 14) {
            first = result._id.toString();
          }
          if (i >= 14) {
            return result;
          }
          return recur();
        });
    }())
    .then(() => {
      this.request(this.app)
        .get(url)
        .set('Authorization', this.authHeader)
        .expect(200)
        .end((err, res) => {
          if (err) {
            done.fail(err.message);
          } else {
            expect(res.body.count).toBe(14);
            expect(res.body.objects.length).toBe(12);
            expect(res.body.objects[0]._id).toEqual(first);
            expect(res.body.objects[11]._id).toEqual(last);
            done();
          }
        });
    });

不确定这是否会在ES2015以下工作,因为我递归使用了生成函数。

当我使用它自己的Promise时,Mongoose会抱怨。然后我在我的测试设置功能之上执行此操作:

const mongoose = require('mongoose');
mongoose.Promise = require('q').Promise;

我希望在这一次测试中浪费这么多时间是值得的:D