Nodejs遍历字符串并保存到具有自动增量长度的mongodb中

时间:2018-04-04 03:09:36

标签: javascript node.js mongoose

在NodeJS中我有这样的字符串

"Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";

我想用相应的套餐和价格保存每个数量。因此,假设我使用数量为3的Package 2,那么它将使用Package Two节省3次,而Price将为702。

所以现在我的代码看起来像这样

const querystring = require('querystring');
const string = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";
const items = string.split('?').filter(Boolean);
var TicketCountQuery = Ticket.count();
for(const query of items) {
    // Parse the query string of each group
    const { Package, Qty, Price } = querystring.parse(query);

    for(let i = 0; i < Number(Qty); i++) {
        console.log('Package Name ' + Package);
        console.log('Package Price ' + Price);

        TicketCountQuery.exec(function (e, count) {
          if( count !== '' ) {
            let TicketId = parseInt(count) + 1;
            console.log(TicketId);
            let ticketData = new Ticket({
              _id           : new mongoose.Types.ObjectId(),
              ticketid      : 'TKT '+ TicketId,
              packagename   : Package,
              price         : Price
            });

            ticketData.save((err) => {
              if( err ) {
                if( err.errors ) {
                  console.log('something went wrong');
                }
              }
              else {
                console.log('tickets saved');
              }
            });
          }
        });
      }
    }

这里的问题是它只是第一次检查mongodb集合。这就是为什么ticketid总是一样的。我希望每个插入都应该增加ticketid。但不知何故它不起作用。有人能告诉我怎么做吗? 任何帮助和建议都会非常明显。

1 个答案:

答案 0 :(得分:1)

问题是您在保存任何故障单之前运行N exec查询,这是因为mongoose.exec异步运行,因此所有查询都将返回相同的count。一个简单的解决方法是使用async/await。根据{{​​3}},如果没有提供回调,.exec会返回一个承诺,因此我们可以轻松等到exec使用await完成

const string = "Package=Package&Qty=1&Price=123?Package=Package Two&Qty=3&Price=702?Package=Package Three&Qty=1&Price=199?Package=Package One&Qty=4&Price=852?";

const qs = require('querystring');

async function processTickets(string) {

    const TicketCountQuery = Ticket.count();

    // We split the string into multiple valid query strings.
    // We strip the empty item due to the '?' at the end using .filter(Boolean)

    const items = string.split('?').filter(Boolean);

    // We loop through each group
    for(const query of items) {
        // Parse the query string of each group
        const { Package, Qty, Price } = qs.parse(query);

        for(let i = 0; i < Number(Qty); i++) {
            // We send the email here <Qty> times.
            console.log('Package Name ' + Package);
            console.log('Package Price ' + Price);

            try {
                // We wait until exec is done
                // No other tickets can be fetched/saved, preventing your problem
                const count = await TicketCountQuery.exec();

                if( count !== '' ) {

                    let TicketId = parseInt(count) + 1;

                    let ticketData = new Ticket({
                        _id: new mongoose.Types.ObjectId(),
                        ticketid: 'TKT ' + TicketId,
                        packagename: Package,
                        price: Price
                    });

                    // We save each ticket one at a time
                    // So the next one will have the correct ID.
                    await ticketData.save();
                    console.log('ticket saved');
                }

            } catch(e) {
                console.log('something went wrong', e);
            }
        }
    }

}

processTickets(string)
    .then(res => {
        console.log('Tickets processed!')
    })
    .catch(err => {
        console.error(err)
    })