简体   繁体   English

Express MongoDB-插入文档,但在通过另一个查询自定义数据之前

[英]Express MongoDB - insert a document but before customize data through another query

My requirement is pretty straightforward - 我的要求非常简单-

I want to insert a document in MongoDB database. 我想在MongoDB数据库中插入一个文档。 But before I have to check if the slug already exists in database. 但是在我必须检查段slug已经存在于数据库中之前。 Then perform an operation to rename the slug if the slug is already exists. 然后,如果段已存在,则执行重命名段的操作。

What I have been trying is to perform an async await callback to check the slug is already exists then insert the document. 我一直在尝试执行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();
});

In console I get undefined value from Promise . 在控制台中,我从Promise获得了undefined值。 Can you please figure out my code? 你能找出我的代码吗?

I am new in MongoDB . 我是MongoDB新手。 So also, do you have the solution of the problem in MongoDB way? 那么,您是否也用MongoDB方式解决了问题? I mean, can I perform these two queries within a single query? 我的意思是,我可以在一个查询中执行这两个查询吗?

Thanks! 谢谢!

  • You don't need to await find() since it's actually the command coming after, in this case count() that is executing the query. 您不需要等待find()因为实际上是后面的命令,在这种情况下, count()正在执行查询。

  • Next I wonder where and how category_info is defined. 接下来,我想知道category_info在哪里以及如何定义。 It's missing in the code above. 上面的代码中缺少它。 But I'll assume you have set it properly in your code. 但是我假设您已经在代码中正确设置了它。

  • You must return something from your async function (a promise preferably). 您必须从异步函数中返回某些内容(最好是一个Promise)。 Right now you only return from the count-callback. 现在,您仅从计数回调中返回。

With async/await you should be able to: 使用异步/等待,您应该能够:

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

Basically, if you use a callback like (err, count)=>{..} then you say "I won't be using promises here!", no promise will come and you have nothing to wait for. 基本上,如果您使用类似(err, count)=>{..}的回调(err, count)=>{..}那么您说“我在这里将不会使用诺言!”,那么诺言就不会来了,您也无需等待。

  • Next: category_promise.then(... this bit is async, so you cannot know that it'll resolve before you start your insertOne( query. Actually you can be almost sure it hasn't. 下一个: category_promise.then(...该位是异步的,因此在启动insertOne(查询之前,您不知道它会解决。实际上,您几乎可以肯定没有。

So you either chain another then: 因此,您要么链另一个,然后:

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

or just async the whole thing: 或只是使整个事情不同步:

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

This code runs, but I haven' tested every case (count and so on), so grain of salt and all that. 这段代码可以运行,但是我还没有测试过每种情况(计数等),所以很难理解。

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

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