简体   繁体   中英

MongoDB aggregation search in objects of array [nodejs, mongoose]

I'm getting from the client side an filter object like:

{
  appId: "01",
  items: [ '60522e84feecf7036fa11831', '60522c47feecf7036fa1182d' ],
  //offset limit
}

my query is:

await someCollection.aggregate([
  { $match: query },
  {
    $group: {//some fields}
  },
])
.sort({date: -1})
.skip(+req.query.offset)
.limit(+req.query.limit)

collection is:

[
  {
    "_id": 1,
    "shop": 1,
    "appId": "01",
    "items": [
      {
        "itemId": "777"
      },
      {
        "itemId": "666"
      },
      
    ]
  },
  {
    "_id": 2,
    "shop": 2,
    "appId": "01",
    "items": [
      {
        "itemId": "666"
      },
      {
        "itemId": "123"
      },
      
    ]
  },
  {
    "_id": 3,
    "shop": 2,
    "appId": "01",
    "items": [
      {
        "itemId": "x"
      },
      
    ]
  }
]

on my Backend query generates dynamically :

const query = {
  '$expr':{
    '$and':[
      {'$eq': ['$appId', req.user.appId.toString()]},
    ]
  }
}

If coming query have a products array I need to search id's in the objects array . for example: ['777', 'x'] as result need to have 2 items where "_id": 1 and "_id": 3

my code is:

if(req.query.products) {
    typeof req.query.products === 'string' ? req.query.products = [req.query.products] : req.query.products
    let bb = req.query.products.map(function(el) { return mongoose.Types.ObjectId(el) })

    query['$expr']['$and'].push({
        $or: [{
            $eq: ['$items.itemId', bb]
        }],
    }
}

mongoplayground

so, I need to use $in operator with $match & $and dynamically, but I have no idea how

I would try it like this:

const query = { ['$or']: [] }

for (let k of Object.keys(req.user)) {
   if (Array.isArray(req.user[k])) {
      for (let i in req.user[k])
         query['$or'].push({ [`${k}.itemId`]: mongoose.Types.ObjectId(i) });
   } else {
      query[k] = req.user[k].toString();
   }
}

await someCollection.aggregate([
  { $match: query },
  {
    $group: {//some fields}
  },
])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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