简体   繁体   English

是否对具有相同更新时间戳的MongoDB文档进行排序?

[英]Sorting MongoDB documents with the same update-timestamps?

I want to test a route in my Express server with Supertest . 我想使用SupertestExpress服务器中测试路由。 On that route i will get a list of data from the MongoDB and that data is sorted by the updatedAt field . 在那条路线上,我将从MongoDB获取数据列表,并且该数据将按updatedAt字段进行排序

I wan to test if the order in the output is the right way, but I have a problem - it seems that mongoDb is so fast that some of the documents have the same timestamp (didn't think that was possible). 我想测试输出中的顺序是否正确,但是我有一个问题-似乎mongoDb是如此之快,以至于某些文档具有相同的时间戳(认为不可能)。

在此处输入图片说明

How is this sorted internally? 内部如何排序? It seems like it is not sorted by _id either. 似乎也没有按_id排序。 Here is the function in my test that generates the documents: 这是我的测试中生成文档的函数:

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();
  }
});

The output is the last 12 items that the user has edited. 输出是用户编辑的最后12个项目。 I save the first and the last so I can assert them later in the test. 我保存了第一个和最后一个,以便稍后在测试中可以断言它们。

But the test fails because there are 3 or 4 with the same timestamp and the one that is actually the last in order of how I put it in the DB is not really the last when Mongo sorts it by timestamps (or first in descending order). 但是测试失败了,因为有3个或4个具有相同的时间戳,而实际上,按照Mongo按时间戳排序(或降序排列)的最后一个实际上并不是我在数据库中放置顺序的最后一个。 。

I tried to make a delay via for-loop in the input-loop but that did nothing. 我试图通过输入循环中的for循环进行延迟,但没有执行任何操作。 (Should I maybe not use Array.forEach?) (我是否应该不使用Array.forEach?)

Is there any way I can make sure that there is at least a few MS delay between the documents? 有什么办法可以确保文档之间至少有几个MS延迟?

Turns out my problem was that I didn't consider the asynchronous nature of all the processes. 原来我的问题是我没有考虑所有流程的异步性质。

I wrapped everything in Promises and it works now. 我将所有内容包装在Promises中,现在可以使用了。 Here is my new code: 这是我的新代码:

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();
          }
        });
    });

Not sure if this would work below ES2015 since I use the generating function recursively. 由于我递归使用生成函数,因此不确定在ES2015以下是否能正常工作。

Mongoose complains when I use it's own Promises. 猫鼬在使用自己的Promises时会抱怨。 Then I do this on top of my test-setup function: 然后,在我的测试设置功能之上执行此操作:

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

I hope it was worth it to waste so much time on this one test :D 我希望花这么多时间在此测试上是值得的:D

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM