Express MongoDB - 在通过另一个查询

时间:2018-06-17 04:06:13

标签: javascript mongodb express

我的要求非常简单 -

我想在MongoDB数据库中插入一个文档。但在我必须检查数据库中是否已存在slug之前。然后,如果slug已经存在,则执行重命名slug的操作。

我一直在尝试执行async await回调以检查slug是否已存在,然后插入文档。

mongoClient.connect(function (err, mongoClient) {
    let db = mongoClient.db("articles");

    let category_information = async (db, category_info) => {
        let slug_information = await db.collection('categories').find({slug: category_info.slug});

        slug_information.count((err, count) => {
            if (count > 0) {
                let new_slug = `${category_info.slug}_${new Date().getTime()}`;
                console.log(new_slug);
                return new_slug;
            }
            else
                return category_info.slug;
        })
    };

    let category_promise = category_information(db, category_info);

    category_promise.then(value => {
        console.log(value);
        category_info.slug = value;
    });

    db.collection('categories')
        .insertOne(category_info, (err, data) => {
            assert.equal(null, err);
            res.status(200);
            res.json('success');
        });

    mongoClient.close();
});

在控制台中,我从undefined获得Promise值。你能搞清楚我的代码吗?

我是MongoDB的新人。那么,您是否以MongoDB的方式解决了问题?我的意思是,我可以在一个查询中执行这两个查询吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

  • 您不需要等待find(),因为它实际上是后来发出的命令,在这种情况下count()正在执行查询。

  • 接下来我想知道category_info的定义位置和方式。它在上面的代码中缺失。但是我假设你已经在代码中正确设置了它。

  • 您必须从异步函数返回一些内容(最好是承诺)。现在你只从count-callback返回。

使用async / await你应该能够:

const count = await slug_information.count();
if (count > 0) {
    let new_slug = `${category_info.slug}_${new Date().getTime()}`;
    console.log(new_slug);
    return new_slug;
} else {
    return category_info.slug;
}

基本上,如果你使用像(err, count)=>{..}那样的回调,那么你说“我不会在这里使用承诺!”,没有承诺会来,你没有什么值得等待的。

  • 下一步:category_promise.then(...这一位是异步的,所以在开始insertOne(查询之前,你无法知道它会解决。实际上你几乎可以肯定它没有。

所以你要么链接另一个:

category_promise.then(value => {
    console.log(value);
    return category_info.slug = value;
}).then( ()=>{ 
    db.collection('categories')
        .insertOne( ...
});

或只是异步整个事情:

const MongoClient = require("mongodb").MongoClient;
const category_info = { slug: "abc" };

async function run(req, res, next) {
  const mongoClient = await MongoClient.connect("mongodb://localhost:27017");
  let db = mongoClient.db("categories");

  // With async/await this is almost superfluous, but lets roll with it.
  let category_information = async (db, category_info) => {
    const count = await db.collection("articles")
      .find({ slug: category_info.slug })
      .count();

    if (count > 0) {
      let new_slug = `${category_info.slug}_${new Date().getTime()}`;
      console.log(new_slug);
      return new_slug;
    } else {
      return category_info.slug;
    }
  };

  category_info.slug = await category_information(db, category_info);
  // note that insertOne() does not return the inserted document.
  let data = await db.collection("categories").insertOne(category_info);

  res.status(200).json(data);

  mongoClient.close();
}

run(); // or app.get("/some-route", run);

这段代码运行了,但是我还没有测试过每一个案例(计数等等),所以这一切都是如此。