Rifat Mahmud
Rifat Mahmud

Reputation: 175

Get some elements from an array mongoDB

In MongoDB shell version v4.4.6 the following code works perfectly.

db['pri-msgs'].findOne({tag:'aaa&%qqq'},{msgs:{$slice:-2}})

But in nodeJs mongoDB the following code doesn't work.

db.collection('pri-msgs').findOne({
  tag: 'aaa&%qqq'
}, {
  msgs: {
    slice: -2
  }
})

My document-->

{"_id":{"$oid":"60c4730fadf6891850db90f9"},"tag":"aaa&%qqq","msgs":[{"msg":"abc","sender":0,"mID":"ctYAR5FDa","time":1},{"msg":"bcd","sender":0,"mID":"gCjgPf85z","time":2},{"msg":"def","sender":0,"mID":"lAhc4yLr6","time":3},{"msg":"efg","sender":0,"mID":"XcBLC2rGf","time":4,"edited":true},{"msg":"fgh","sender":0,"mID":"9RWVcEOlD","time":5},{"msg":"hij","sender":0,"mID":"TJXVTuWrR","time":6},{"msg":"jkl","sender":0,"mID":"HxUuzwrYN","time":7},{"msg":"klm","sender":0,"mID":"jXEOhARC2","time":8},{"msg":"mno","sender":0,"mID":"B8sVt4kCy","time":9}]}

Actually what I'm trying to do is Get last 2 itmes from msgs Array where time is greater than 'n'. Here 'n' is a number.

Upvotes: 0

Views: 57

Answers (1)

Duy Quoc
Duy Quoc

Reputation: 181

You can use aggregation-pipeline to get the results you are looking for. The steps are the following.

  1. Match the documents you want by tag.
  2. Unwind the msgs array.
  3. Sort descending by msgs.time.
  4. Limit first 2 elements.
  5. Match the time you are looking for using a range query.
  6. Group the documents back by _id.

Your query should look something like this:

db['pri-msgs'].aggregate([
  { $match: { tag: 'aaa&%qqq' } },
  { $unwind: '$msgs' },
  {
    $sort: {
      'msgs.time': -1 //DESC
    }
  },
  { $limit: 2 },
  {
    $match: {
      'msgs.time': {
        $gt: 2 //n
      }
    }
  },
  {
    $group: {
      _id: '$_id',
      tag: { $first: '$tag' },
      msgs: {
        $push: { msg: '$msgs.msg', sender: '$msgs.sender', mID: '$msgs.mID', time: '$msgs.time' }
      }
    }
  }
]);

Upvotes: 1

Related Questions