Yatin Pandit
Yatin Pandit

Reputation: 57

How to run a query inside an array in mongodb

I have a Database in Mongo. I need to find all the samples within a particular time.

[
  {
    deviceid: 1,
    bucketSize: 4,
    first: 1573833152,
    last: 1573833155,
    samples: [
      {
        val: 10,
        time: 1573833152
      },
      {
        val: 15,
        time: 1573833153
      },
      {
        val: 14,
        time: 1573833154
      },
      {
        val: 20,
        time: 1573833155
      }
    ]
  },
  {
    deviceid: 1,
    bucketSize: 4,
    first: 1573833156,
    last: 1573833160,
    samples: [
      {
        val: 10,
        time: 1573833156
      },
      {
        val: 15,
        time: 1573833157
      },
      {
        val: 14,
        time: 1573833158
      },
      {
        val: 20,
        time: 1573833159
      },
      {
        val: 20,
        time: 1573833160
      }
    ]
  },
  {
    deviceid: 1,
    bucketSize: 4,
    first: 1573833161,
    last: 1573833165,
    samples: [
      {
        val: 10,
        time: 1573833161
      },
      {
        val: 15,
        time: 1573833162
      },
      {
        val: 14,
        time: 1573833163
      },
      {
        val: 20,
        time: 1573833164
      }
    ]
  }
]

Eg: samples between 1573833152 and 1573833156

should yield

samples: [
      {
        val: 10,
        time: 1573833152
      },
{
        val: 15,
        time: 1573833153
      },
   {
        val: 14,
        time: 1573833154
      },
      {
        val: 20,
        time: 1573833155
      },      {
        val: 10,
        time: 1573833156
      }

I tried all methods but failed to extract the required results. Thank You So much in advance.I tried using $or, $elemMatch. But as I am new to Mongo I failed. If someone can please help

Upvotes: 0

Views: 77

Answers (2)

Samim Hakimi
Samim Hakimi

Reputation: 725

Try this one:

 samples.find({
     $elemMatch: {
         $gte: 1573833152,
         $lte: 1573833156
     }
 })

Upvotes: 0

Joe
Joe

Reputation: 28316

You'll need to use aggregation for that.

  • First match the timestamps against the samples array so you only consider documents that contain at least one sample you care about
  • unwind samples so each document contains only 1 sample
  • match the timestamps again to eliminate the extraneous samples
  • sort by timestamp, if desired
  • group by _null, pushing each sample onto an array
db.collection.aggregate([
    {$match: { "samples.time": { $gte: 1573833152, $lte: 1573833156 }}},
    {$unwind: "$samples"},
    {$match: { "samples.time": { $gte: 1573833152, $lte: 1573833156 }}},
    {$sort: { "samples.time": 1}},
    {$group: { _id:null, samples:{$push:"$samples"}}}
])

Playground

Upvotes: 1

Related Questions