Home > Blockchain >  Problem with query on nested document in MongoDB
Problem with query on nested document in MongoDB

Time:04-12

I would like to get price and date info and send to ejs the between two specific dates and names.

My first document is like this and I have many. For instance I want all Bitcoin infos between 2022-4-1 and 2022-4-6. Without nested it works but in this case I couldn't do.

{
   "_id" : ObjectId("62175a6dd2b42d83134288f0"),
   "result" : [ 
       {
           "name" : "Bitcoin",
           "symbol" : "BTC",
           "price" : 45488.969940933,
           "date" : "2022-4-1",
           "time" : "16:25:22",
           "active" : 1
       }, 
       {
           "name" : "Ethereum",
           "symbol" : "ETH",
           "price" : 3328.61487109438,
           "date" : "2022-4-1",
           "time" : "16:25:22",
           "active" : 1
       }, 
   //..and goes to 100
      
   ]
}

myDocuments

I've tried

dbo.collection("info").find({ result : {name:"Bitcoin"}, date: { $gte: "2022-4-1", $lte: "2022-4-6" }.toArray //Getting an empty []
dbo.collection("info").find({ 'result.name' :"Bitcoin"}).toArray //Getting all of documents in the DB.
dbo.collection("info").find({"result": { $elemMatch:{"name": "Bitcoin"}}}).toArray //Same as above.

I have also tried without .toArray and findOne and nothing changed. Many thanks.

First object's full JSON is https://pastebin.com/06V4upPY

CodePudding user response:

db.collection.find({
  result: {
    $elemMatch: {
      name: "Bitcoin",
      date: {
        $gte: "2022-4-1",
        $lte: "2022-4-6"
      }
    }
  }
},
{
  "result.$": 1
})

mongoplayground

CodePudding user response:

It's normal that the second and third query return all documents because if all documents have a Bitcoin element in the result array it will return the document.

The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.

Source $elemMatch (query) doc

For filter only the bitcoin element you must $elemMatch in the projection part Like this :

dbo.collection("info").find({ 
  'result.name' :"Bitcoin"
}, 
{
  'result': {
      $elemMatch: {
         "name": "Bitcoin" 
      }
   }
)

MongoPlayground

The $elemMatch operator limits the contents of an field from the query results

Source : $elemMatch (projection) doc

  • Related