Mongodb aggregate run in terminal but when run in node.js with mongoose it's return "APIError: Arguments must be aggregate pipeline operators"

Mongodb aggregate run in terminal but when run in node.js with mongoose it's return "APIError: Arguments must be aggregate pipeline operators"

当我 运行 mongo 中的聚合抛出终端时 returns 正确的数据,但是当我 运行 代码中的相同聚合时 returns 一个错误。

我曾尝试只使用 match 和 group 来测试,但即使我使用了 mongoose 函数但没有任何运气,我仍然会遇到同样的错误

我打算尝试改进我的综合游戏,但现在,我需要这个 运行,最近几天我被困在这里。

"APIError: Arguments must be aggregate pipeline operators\n    at new ExtendableError (/vagrant/server/helpers/APIError.js:15:11)\n    at new APIError (/vagrant/server/helpers/APIError.js:31:5)\n    at app.use (/vagrant/config/express.js:64:22)\n    at Layer.handle_error (/vagrant/node_modules/express/lib/router/layer.js:71:5)\n    at trim_prefix (/vagrant/node_modules/express/lib/router/index.js:315:13)\n    at /vagrant/node_modules/express/lib/router/index.js:284:7\n    at Function.process_params (/vagrant/node_modules/express/lib/router/index.js:335:12)\n    at next (/vagrant/node_modules/express/lib/router/index.js:275:10)\n    at /vagrant/node_modules/express/lib/router/index.js:635:15\n    at Immediate.next (/vagrant/node_modules/express/lib/router/index.js:260:14)\n    at Immediate._onImmediate (/vagrant/node_modules/express/lib/router/index.js:635:15)\n    at runCallback (timers.js:706:11)\n    at tryOnImmediate (timers.js:676:5)\n    at processImmediate (timers.js:658:5)"

客户模型

const mongoose = require('mongoose');
const customerContactsSchema = require('./customerContacts.model');
const appSettings = require('../../config/appSettings');

/**
 * Customer Schema
 */
const CustomerSchema = new mongoose.Schema({
  avatar: {
    type: String,
    required: false
  },
  firstName: {
    type: String,
    required: false
  },
  lastName: {
    type: String,
    required: false
  },
  password: {
    type: String,
    required: false,
    select: false
  },
  address: {
    country: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Country',
      required: false
    },
    city: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'City',
      required: false
    },
  },
  language: {
    type: String,
    required: true,
    enum: appSettings.languages,
    default: 'english'
  },
  mobileNumber: {
    number: {
      type: String,
      required: true,
      trim: true
    },
    country: {
      type: mongoose.Schema.Types.ObjectId,
      ref: 'Country',
      required: true
    }
  },
  email: {
    type: String,
    lowercase: true,
    trim: true,
    required: false
  },
  birthday: {
    type: Date,
    required: false
  },
  gender: {
    type: String,
    enum: ['male', 'female'],
    required: false
  },
  friends: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Customer',
    required: false
  }],
  contacts: [customerContactsSchema],
  favourites: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Company',
    required: false
  }],
  transactions: [{
    type: mongoose.Schema.Types.ObjectId,
    ref: 'CustomerTransaction',
    required: false
  }],
  googleId: {
    type: String
  },
  facebookId: {
    type: String
  },
  twitterId: {
    type: String
  },
  fcmToken: {
    type: String
  },
  otpToken: {
    type: Number,
    required: false,
    default: 1234
  },
  otpTokenExpiration: {
    type: Date,
    required: false
  },
  status: {
    type: String,
    enum: ['active', 'pending', 'suspended', 'blocked', 'deleted'],
    required: true,
    default: 'pending'
  }
}, { timestamps: true });


/**
 * @typedef Customer
 */
module.exports = mongoose.model('Customer', CustomerSchema);

CustomerTransaction 模型

const mongoose = require('mongoose');
const locationSchema = require('./location.model');

/**
 * CustomerTransaction Schema
 */
const CustomerTransactionSchema = new mongoose.Schema({
  company: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Company',
    required: true
  },
  customer: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Customer',
    required: true
  },
  type: {
    type: String,
    // debit - , credit +
    enum: ['debit', 'credit'],
    required: true
  },
  expirationDate: {
    type: Date,
    required: false
  },
  point: {
    amount: {
      type: Number,
      required: false
    },
    value: {
      type: Number,
      required: false
    }
  },
  closeValue: {
    type: Number,
    required: false
  },
  closePoints: {
    type: Number,
    required: false
  },
  offer: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Offer',
    required: false
  },
  voucher: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Voucher',
    required: false
  },
  stamp: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Stamp',
    required: false
  },
  punches: {
    type: Number,
    required: false
  },
  date: {
    type: Date,
    required: false,
    default: Date.now()
  },
  gift: {
    type: Boolean,
    default: false
  },
  giftSender: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Customer',
    required: false
  },
  giftReceiver: {
    type: mongoose.Schema.Types.ObjectId,
    ref: 'Customer',
    required: false
  },
  status: {
    type: String,
    enum: ['active', 'used', 'sent', 'expired', 'deleted'],
    required: true,
    default: 'active'
  },
  location: locationSchema
}, { timestamps: true });


/**
 * @typedef CustomerTransaction
 */
module.exports = mongoose.model('CustomerTransaction', CustomerTransactionSchema);

汇总

db.getCollection('customers').aggregate([
    {
      $match: {
        gender: new RegExp(`.*${'' || ''}.*`, 'i'),
        birthday: {
          $gte: ISODate('1991-04-29T00:00:00.000Z'),
          $lte: ISODate('2019-04-29T00:00:00.000Z'),
        },
        createdAt: {
          $gte: ISODate('1991-04-29T00:00:00.000Z'),
          $lte: ISODate('2019-04-29T00:00:00.000Z'),
        },
      }
    },
    {
      $lookup: {
        from: 'customertransactions',
        localField: '_id',
        foreignField: 'customer',
        as: 'CustomerTransaction'
      }
    },
    {
      $match: {
        'CustomerTransaction.company': ObjectId('5cd2af3a5bfc5b1a40b7de49'),
      }
    },
    {
      $project: {
        firstName: 1,
        lastName: 1,
        CustomerTransaction: 1,
        CustomerStampTransaction: {
          $setDifference: [
            {
              $map: {
                input: '$CustomerTransaction',
                as: 'el',
                in: {
                  $cond: [
                    {
                      $and: [
                        { $gte: ['$$el.stamp', 1] },
                        { $lt: ['$$el.offer', 0] },
                        { $lt: ['$$el.voucher', 0] },
                        { $eq: ['$$el.company', ObjectId('5cd2af3a5bfc5b1a40b7de49')] }
                      ]
                    },
                    {
                      _id: '$$el._id'
                    },
                    false
                  ]
                }
              }
            },
            [false]
          ]
        },
        CustomerPointTransaction: {
          $setDifference: [
            {
              $map: {
                input: '$CustomerTransaction',
                as: 'el',
                in: {
                  $cond: [
                    {
                      $and: [
                        { $lt: ['$$el.stamp', 0] },
                        { $lt: ['$$el.offer', 0] },
                        { $lt: ['$$el.voucher', 0] },
                        { $eq: ['$$el.company', ObjectId('5cd2af3a5bfc5b1a40b7de49')] }
                      ]
                    },
                    {
                      _id: '$$el._id',
                      createdAt: '$$el.createdAt',
                      closePoints: '$$el.closePoints',
                    },
                    false
                  ]
                }
              }
            },
            [false]
          ]
        }
      }
    },
    {
      $project: {
        firstName: 1,
        lastName: 1,
        CustomerPointTransaction: 1,
        stampCount: {
          $cond: {
            if: { $isArray: '$CustomerStampTransaction' },
            then: { $size: '$CustomerStampTransaction' },
            else: 0
          }
        },
        //"CustomerTransaction": "$CustomerTransaction"
      }
    },
    {
      $unwind: {
        path: '$CustomerPointTransaction',
        preserveNullAndEmptyArrays: true
      }
    },
    { $sort: { 'CustomerPointTransaction.createdAt': 1 } },
    {
      $group: {
        _id: '$_id',
        firstName: { $first: '$firstName' },
        lastName: { $first: '$lastName' },
        stampCount: { $first: '$stampCount' },
        CustomerPointTransaction: { $last: '$CustomerPointTransaction' }
      }
    },
    {
      $group: {
        _id: '$_id',
        firstName: { $first: '$firstName' },
        lastName: { $first: '$lastName' },
        stampCount: { $first: '$stampCount' },
        pointCount: { $first: '$CustomerPointTransaction.closePoints' }
      }
    },
  ]);

汇总结果

{ "_id" : ObjectId("5c8918ab9979f345214158ba"), "firstName" : "mohammed", "lastName" : "alqahtani", "stampCount" : 1, "pointCount" : null }
{ "_id" : ObjectId("5cc161039f11d13109185b15"), "firstName" : "Mohammedaadsxxxa", "lastName" : "AlQahtaniss", "stampCount" : 0, "pointCount" : 9 }

代码

function search(req, res) {
  Customer.aggregate([
    {
      $match: {
        gender: new RegExp(`.*${'' || ''}.*`, 'i'),
      }
    },
    {
      $lookup: {
        from: 'customertransactions',
        localField: '_id',
        foreignField: 'customer',
        as: 'CustomerTransaction'
      }
    },
    {
      $match: {
        'CustomerTransaction.company': req.company._id,
      }
    },
    {
      $project: {
        firstName: 1,
        lastName: 1,
        CustomerTransaction: 1,
        CustomerStampTransaction: {
          $setDifference: [
            {
              $map: {
                input: '$CustomerTransaction',
                as: 'el',
                in: {
                  $cond: [
                    { $and: [
                        { $gte: ['$$el.stamp', 1] },
                        { $lt: ['$$el.offer', 0] },
                        { $lt: ['$$el.voucher', 0] },
                        { $eq: ['$$el.company', req.company._id] }
                    ] },
                    {
                      _id: '$$el._id'
                    },
                    false
                  ]
                }
              }
            },
            [false]
          ]
        },
        CustomerPointTransaction: {
          $setDifference: [
            {
              $map: {
                input: '$CustomerTransaction',
                as: 'el',
                in: {
                  $cond: [
                    { $and: [
                        { $lt: ['$$el.stamp', 0] },
                        { $lt: ['$$el.offer', 0] },
                        { $lt: ['$$el.voucher', 0] },
                        { $eq: ['$$el.company', req.company._id] }
                    ] },
                    {
                      _id: '$$el._id',
                      createdAt: '$$el.createdAt',
                      closePoints: '$$el.closePoints',
                    },
                    false
                  ]
                }
              }
            },
            [false]
          ]
        }
      }
    },
    {
      $project: {
        firstName: 1,
        lastName: 1,
        CustomerPointTransaction: 1,
        stampCount: { $cond: { if: { $isArray: '$CustomerStampTransaction' }, then: { $size: '$CustomerStampTransaction' }, else: 0 } },
        //"CustomerTransaction": "$CustomerTransaction"
      }
    },
    {
      $unwind: {
        path: '$CustomerPointTransaction',
        preserveNullAndEmptyArrays: true
      }
    },
    { $sort: { 'CustomerPointTransaction.createdAt': 1 } },
    {
      $group: {
        _id: '$_id',
        firstName: { $first: '$firstName' },
        lastName: { $first: '$lastName' },
        stampCount: { $first: '$stampCount' },
        CustomerPointTransaction: { $last: '$CustomerPointTransaction' }
      }
    },
    {
      $group: {
        _id: '$_id',
        firstName: { $first: '$firstName' },
        lastName: { $first: '$lastName' },
        stampCount: { $first: '$stampCount' },
        pointCount: { $first: '$CustomerPointTransaction.closePoints' }
      }
    },
  ], { cursor: {} })
    .then((customers) => {
      console.log('kkkkkkkkk');
      if (customers) {
        res.json(Response.success(customers));
      } else {
        res.json(Response.success('klklk'));
      }
    })
    .catch(err => res.status(httpStatus.INTERNAL_SERVER_ERROR)
      .json(Response.failure(err)));
}

请记住,即使我 运行 下面的代码仍然会抛出相同的错误

function search(req, res) {
  Customer.aggregate([
    {
      $match: {
        gender: new RegExp(`.*${'' || ''}.*`, 'i'),
      }
    }
  ], { cursor: {} })
    .then((customers) => {
      console.log('kkkkkkkkk');
      if (customers) {
        res.json(Response.success(customers));
      } else {
        res.json(Response.success('klklk'));
      }
    })
    .catch(err => res.status(httpStatus.INTERNAL_SERVER_ERROR)
      .json(Response.failure(err)));
}
Customer.aggregate([
    {
      $match: {
        gender: new RegExp(`.*${'' || ''}.*`, 'i'),
      }
    }
  ], { cursor: {} }) // ERROR IS HERE

对于 mongoose 和 .aggregate,没有像 .find 那样的选项参数。试试这个

Customer.aggregate([
{
  $match: {
    gender: new RegExp(`.*${'' || ''}.*`, 'i'),
  }
}
]).cursor()

已更新

Customer.aggregate([
{
  $match: {
    gender: new RegExp(`.*${'' || ''}.*`, 'i'),
  }
}
]).exec((error, docs) => {
    console.log(docs)
    res.json(docs)
})

这对我有用吗

async function search(req, res) {
  try {
    const customers = await Customer.aggregate([
      {
        $match: {
          gender: 'male'
        }
      }
      ]
    )
      .cursor({})
      .exec();
    customers.get(function(err, ress){
      if (ress) {
        res.json(Response.success(ress));
      } else {
        res.json(Response.success('klklk'));
      }
    });

  } catch(e) {
    res.status(httpStatus.INTERNAL_SERVER_ERROR) .json(Response.failure(e));
  }

}

但我无法弄清楚为什么它可以工作以及我以前的代码有什么问题