Limit results of Mongodb find() query not working - mongodb

I must be overlooking really simple, here's a sample of my db :
{ "_id" : ObjectId("545e7e45a69b6c5c0caeafcc"), "url" : "http://example.com/id=4314936", "name" : "product1", "retailer" : "123", "extra" : [ ], "timestamp" : 1415478797263, "processed" : 0 }
{ "_id" : ObjectId("545e7e45a69b6c5c0caeafcc"), "url" : "http://example.com/id=4314936", "name" : "product2", "retailer" : "123", "extra" : [ ], "timestamp" : 1415478797263, "processed" : 0 }
{ "_id" : ObjectId("545e7e45a69b6c5c0caeafcc"), "url" : "http://example.com/id=4314936", "name" : "product3", "retailer" : "123", "extra" : [ ], "timestamp" : 1415478797263, "processed" : 0 }
{ "_id" : ObjectId("545e7e45a69b6c5c0caeafcc"), "url" : "http://example.com/id=4314936", "name" : "product3", "retailer" : "123", "extra" : [ ], "timestamp" : 1415478797263, "processed" : 0 }
I'm trying to get 2 results only using :
db.products.find({timestamp:1415478797263,processed:0},{},{limit:2})
I have read and tried similar questions on Stack Overflow, so please keep that in mind before flagging as duplicate.
No matter what I try it gives me the full set... The strangest thing is that I'm using a similar find() elsewhere and it works. An experienced pair of eyes should be able to spot the problem, thanks in advance!!

use this query, does it work?
db.products.find({timestamp:1415478797263,processed:0}).limit(2)
now to use it with node js native driver you can do this
db.products.find({timestamp:1415478797263,processed:0}).limit(2).each(function(err, doc) {
console.dir(doc);
});
or in array form you can get this as
db.products.find({timestamp:1415478797263,processed:0}).limit(2).toArray(function(err, docs) {
console.log("Returned #" + docs.length + " documents");
})

Related

mongoose: find value inside object, inside array inside array of objects

Hello and sorry for the title,
it is quite hard to explain with words.
I have a data with multiples level :
-strategyParameters -> [wsent -> [ {confirmationCandle.timestamp} ] ]
I am trying to request documents, having inside wSent, inside strategyParameters, a confirmationCandle timestamp greater than a certain value.
I have tried several attemps with some things similar to this :
db.getCollection('users').find({"exchange":"binance","pair":"LTCUSDT","timeframe":"1h","wSent.confirmationCandle.timestamp":{"$gt":1606644800000}})
But it was unsuccessful, any help would be much appreciated.
bellow a concrete example of document inside my db:
{
"_id" : ObjectId("5fd7b0f1356b89312949963a"),
"email" : "test#test.com",
"password" : "$2b$10$egeg",
"strategyParameters" : [
{
"_id" : ObjectId("5fd7c9940d0f3033fc527547"),
"pair" : "LTCUSDT",
"strategy" : "w",
"timeframe" : "1h",
"exchange" : "binance",
"wSent" : [
{
"_id" : ObjectId("5fd7adb9d157b430a05a87b1"),
"firstBottom" : {
"open" : 79.46,
"high" : 80.07,
"low" : 78.29,
"close" : 78.91,
"timestamp" : 1606690800000.0,
"isTop" : false,
"isBottom" : true
},
"top" : {
"open" : 78.89,
"high" : 80.5,
"low" : 78.87,
"close" : 79.7,
"timestamp" : 1606694400000.0,
"isTop" : true,
"isBottom" : false
},
"seconBottom" : {
"open" : 79.73,
"high" : 79.84,
"low" : 78.55,
"close" : 79.29,
"timestamp" : 1606698000000.0,
"isTop" : false,
"isBottom" : true
},
"confirmationCandle" : {
"open" : 81.56,
"high" : 85,
"low" : 81.1,
"close" : 83.24,
"timestamp" : 1606744800000.0, <-- the target
"isTop" : false,
"isBottom" : false
},
"exchange" : "binance",
"pair" : "LTCUSDT",
"timeframe" : "1h"
}
]
}
]
}
Your query doesn't match because the fields you're searching for don't align with the document's structure. The sample document doesn't have exchange, pair, timeframe or wSent.confirmationCandle.timestamp fields. But it does have strategyParameters.wSent.exchange, strategyParameters.wSent.pair, strategyParameters.wSent.timeframe and strategyParameters.wSent.confirmationCandle.timestamp fields.
Your query should look something like this:
db.getCollection("users").find({
"strategyParameters.wSent.exchange": "binance",
"strategyParameters.wSent.pair": "LTCUSDT",
"strategyParameters.wSent.timeframe": "1h",
"strategyParameters.wSent.confirmationCandle.timestamp": { $gt :1606644800000 }
})

MongoDB addToSet in nested array

I'm struggling to insert data inside a nested array in MongoDB.
My schema looks like this:
{
"_id" : ObjectId("5c0c55642440311ff0353846"),
"name" : "Test",
"email" : "test#gmail.com",
"username" : "test",
"password" : "$2a$10$RftzGtgM.DqIiaSvH4LqOO6RnLgQfLY3nk7UIAH4OAvvxo0ZMSaHu",
"created" : ISODate("2018-12-08T23:36:04.464Z"),
"classes" : [
{
"_id" : ObjectId("5c0c556e2440311ff0353847"),
"cName" : "1A",
"student" : [
{
"grades" : [ ],
"_id" : ObjectId("5c0c55812440311ff0353848"),
"name" : "StudentName",
"lname" : "StudenteLastName",
"gender" : "M"
}
insert }
],
"__v" : 0
}.
What I want to do is inserting a grade for the student inside "grades" array.
Expected result is:
{
"_id" : ObjectId("5c0c55642440311ff0353846"),
"name" : "Test",
"email" : "test#gmail.com",
"username" : "test",
"password" : "$2a$10$RftzGtgM.DqIiaSvH4LqOO6RnLgQfLY3nk7UIAH4OAvvxo0ZMSaHu",
"created" : ISODate("2018-12-08T23:36:04.464Z"),
"classes" : [
{
"_id" : ObjectId("5c0c556e2440311ff0353847"),
"cName" : "1A",
"student" : [
{
"grades" : [6],
"_id" : ObjectId("5c0c55812440311ff0353848"),
"name" : "StudentName",
"lname" : "StudenteLastName",
"gender" : "M"
}
]
}
],
"__v" : 0
}.
I tried some queries but none of them helped me, even searching a lot.
db.teachers.update({"_id": ObjectId("5c0c55642440311ff0353846"), "classes._id": ObjectId("5c0c556e2440311ff0353847"), "classes.student._id": ObjectId("5c0c55812440311ff0353848")},{$addToSet: {"classes.$.student.grades":6}})
Basically, I searched for the student with the first curly bracket (if I do "db.teachers.find(the three conditions) the result is correct) and then add to the grades array (of Integer) the value 6. But at this point I get errors, I think I'm making a mistake on the "adding" part.
I need also to do the same thing in Mongoose.
Any help is appreciated, thanks in advance!
Edit: I solved. I post my solution hoping it'll be useful to other:
For pushing inside a triple nested array do:
db.teachers.update({"_id":ObjectId("5c0c59985ae5981c58937e12"),"classes":{ $elemMatch : { _id : ObjectId("5c0c59a35ae5981c58937e13") }},"classes.student": { $elemMatch : { _id : ObjectId("5c0c59aa5ae5981c58937e14")} }},{$addToSet:{"classes.$.student.0.grades":3}})
https://docs.mongodb.com/manual/tutorial/query-array-of-documents/
Try using $elemMatch
"classes":{ $elemMatch : { _id : ObjectId("5c0c556e2440311ff0353847") }},
"classes.student": { $elemMatch : { _id : ObjectId("5c0c55812440311ff0353848")} }

is it possible to use "or" in query part of update method in mongodb

Can I use or in query part of update method in mongodb.
If yes then what am I doing wrong because the upsert is not working.
I get two different type of result when I use and don't use or.
when I use or only the data.message is inserted and when I use don't use or all the data is inserted if it does not exist and it exist data.messages gets added to messages.
db.chatdata.update(
{$or:[
{'receiverId':data.receiver_id,
'senderId':data.sender_id
},
{'receiverId':data.sender_id,
'senderId':data.receiver_id
}]
},
{$addToSet:{'messages':data.message}},
{upsert:true},
callback)
expected output
{
"_id" : ObjectId("5986f850e1bf9b531154e52d"),
"receiverId" : "5985864dd06db71fa4c2ce69",
"senderId" : "59857707f6de9106fc936003",
"messages" : [
{
"_id" : ObjectId("5986f8509bda810a140e975d"),
"message" : "hello apple",
"time" : "1502017616523"
},
{
"_id" : ObjectId("5986f8a19bda810a140e9768"),
"message" : "hello apple",
"time" : "1502017697484"
}
],
"__v" : 0
}
actual output
{
"_id" : ObjectId("59872ec4e1bf9b531154eedd"),
"messages" : [
{
"_id" : ObjectId("59872ec4827f9737949589f3"),
"message" : "helo",
"time" : "1502031556694"
}
],
"__v" : 0
}

Get document based on multiple criteria of embedded collection

I have the following document, I need to search for multiple items from the embedded collection"items".
Here's an example of a single SKU
db.sku.findOne()
{
"_id" : NumberLong(1192),
"description" : "Uploaded via CSV",
"items" : [
{
"_id" : NumberLong(2),
"category" : DBRef("category", NumberLong(1)),
"description" : "840 tag visual",
"name" : "840 Visual Mini Round",
"version" : NumberLong(0)
},
{
"_id" : NumberLong(7),
"category" : DBRef("category", NumberLong(2)),
"description" : "Maxi",
"name" : "Maxi",
"version" : NumberLong(0)
},
{
"_id" : NumberLong(11),
"category" : DBRef("category", NumberLong(3)),
"description" : "Button",
"name" : "Button",
"version" : NumberLong(0)
},
{
"_id" : NumberLong(16),
"category" : DBRef("category", NumberLong(4)),
"customizationFields" : [
{
"_class" : "CustomizationField",
"_id" : NumberLong(1),
"displayText" : "Custom Print 1",
"fieldName" : "customPrint1",
"listOrder" : 1,
"maxInputLength" : 12,
"required" : false,
"version" : NumberLong(0)
},
{
"_class" : "CustomizationField",
"_id" : NumberLong(2),
"displayText" : "Custom Print 2",
"fieldName" : "customPrint2",
"listOrder" : 2,
"maxInputLength" : 17,
"required" : false,
"version" : NumberLong(0)
}
],
"description" : "2 custom lines of farm print",
"name" : "Custom 2",
"version" : NumberLong(2)
},
{
"_id" : NumberLong(20),
"category" : DBRef("category", NumberLong(5)),
"description" : "Color Red",
"name" : "Red",
"version" : NumberLong(0)
}
],
"skuCode" : "NF-USDA-XC2/SM-BC-R",
"version" : 0,
"webCowOptions" : "840miniwithcust2"
}
There are repeat items.id throughout the embedded collection. Each Sku is made up of multiple items, all combinations are unique, but one item will be part of many Skus.
I'm struggling with the query structure to get what I'm looking for.
Here are a few things I have tried:
db.sku.find({'items._id':2},{'items._id':7})
That one only returns items with the id of 7
db.sku.find({items:{$all:[{_id:5}]}})
That one doesn't return anything, but it came up when looking for solutions. I found about it in the MongoDB manual
Here's an example of a expected result:
sku:{ "_id" : NumberLong(1013),
"items" : [ { "_id" : NumberLong(5) },
{ "_id" : NumberLong(7) },
{ "_id" : NumberLong(12) },
{ "_id" : NumberLong(16) },
{ "_id" :NumberLong(2) } ] },
sku:
{ "_id" : NumberLong(1014),
"items" : [ { "_id" : NumberLong(5) },
{ "_id" : NumberLong(7) },
{ "_id" : NumberLong(2) },
{ "_id" : NumberLong(16) },
{ "_id" :NumberLong(24) } ] },
sku:
{ "_id" : NumberLong(1015),
"items" : [ { "_id" : NumberLong(5) },
{ "_id" : NumberLong(7) },
{ "_id" : NumberLong(12) },
{ "_id" : NumberLong(2) },
{ "_id" :NumberLong(5) } ] }
Each Sku that comes back has both a item of id:7, and id:2, with any other items they have.
To further clarify, my purpose is to determine how many remaining combinations exist after entering the first couple of items.
Basically a customer will start specifying items, and we'll weed it down to the remaining valid combinations. So Sku.items[0].id=5 can only be combined with items[1].id=7 or items[1].id=10 …. Then items[1].id=7 can only be combined with items[2].id=20 … and so forth
The goal was to simplify my rules for purchase, and drive it all from the Sku codes. I don't know if I dug a deeper hole instead.
Thank you,
On the part of extracting the sku with item IDs 2 and 7, when I recall correctly, you have to use $elemMatch:
db.sku.find({'items' :{ '$all' :[{ '$elemMatch':{ '_id' : 2 }},{'$elemMatch': { '_id' : 7 }}]}} )
which selects all sku where there is each an item with _id 2 and 7.
You can use aggregation pipelines
db.sku.aggregate([
{"$unwind": "$sku.items"},
{"$group": {"_id": "$_id", "items": {"$addToSet":{"_id": "$items._id"}}}},
{"$match": {"items._id": {$all:[2,7]}}}
])

mongodb $maxScan didn't equals limit

This is my first question on stack overflow, I am so happy and await your answers. My question is:
When I use MongoDB Query Selectors, I want limit results. But $maxScan is not work as I want.
---------This is What I want result.
db.post.find({query:{status:"publish"},$orderby:{date:-1}},{status:1,name:1,date:1,$slice:2}).limit(3)
{ "_id" : ObjectId("519262580cf21fb1647fb765"), "date" : ISODate("2013-05-14T16:12:08.600Z"), "status" : "publish", "name" : "关于多说" }
{ "_id" : ObjectId("519254ad0cf2f064f6ecef82"), "date" : ISODate("2013-05-14T15:13:49.017Z"), "status" : "publish", "name" : "回顾<蜗居>的100句经典台词" }
{ "_id" : ObjectId("519254690cf2f064f6ecef81"), "date" : ISODate("2013-05-14T15:12:41.462Z"), "status" : "publish", "name" : "女人脱光了是什么" }
-----------This is the results I use $maxScan
db.post.find({query:{status:"publish"},$maxScan:3,$orderby:{date:-1}},{status:1,name:1,date:1})
{ "_id" : ObjectId("518e6c690cf21a363df2956e"), "date" : ISODate("2013-05-11T16:06:01.341Z"), "status" : "publish", "name" : "淘宝新店,充值任务" }
I find may be the $maxScan didn't like limit(). it first limit the collection data and then execute the query! but this is not I want. Is anything i wrong? please help.Thanks
--------------All results
db.post.find({query:{},$orderby:{date:-1}},{status:1,name:1,date:1})
{ "_id" : ObjectId("519262580cf21fb1647fb765"), "date" : ISODate("2013-05-14T16:12:08.600Z"), "status" : "publish", "name" : "关于多说" }
{ "_id" : ObjectId("519254ad0cf2f064f6ecef82"), "date" : ISODate("2013-05-14T15:13:49.017Z"), "status" : "publish", "name" : "回顾<蜗居>的100句经典台词" }
{ "_id" : ObjectId("519254690cf2f064f6ecef81"), "date" : ISODate("2013-05-14T15:12:41.462Z"), "status" : "publish", "name" : "女人脱光了是什么" }
{ "_id" : ObjectId("518ee61a0cf22bd326d60215"), "date" : ISODate("2013-05-12T00:45:14.295Z"), "status" : "publish", "name" : "JSTL日期格式化用法(转载)" }
{ "_id" : ObjectId("518e6c690cf21a363df2956e"), "date" : ISODate("2013-05-11T16:06:01.341Z"), "status" : "publish", "name" : "淘宝新店,充值任务" }
{ "_id" : ObjectId("518e21c90cf21a363df2956d"), "date" : ISODate("2013-05-11T10:47:37.803Z"), "status" : "draft", "name" : "一夜没睡" }
{ "_id" : ObjectId("518df75d0cf21a363df2956c"), "date" : ISODate("2013-05-11T07:46:37.726Z"), "status" : "draft", "name" : "飞娥入侵" }
{ "_id" : ObjectId("518d80630cf21a363df2956b"), "date" : ISODate("2013-05-10T23:18:59.323Z"), "status" : "publish", "name" : "Java的日期格式化常用方法" }
To return only the top results, you should use limit(), which will limit the amount of results returned from the cursor. This is commonly used with skip() to paginate the results.
It's not explained very clearly in the docs, but $maxScan as the name suggests limits the number of documents the query will examine. Presumably your query is examining some documents which don't meet the criteria (with status != publish) and then discarding them.
Do you have an index on status? It's possible that could help the query return the results you want while scanning fewer documents, but I still think limit() is what you want.