I am having mongo DB collection namely student with the following document structure,
name:details:date:values
so, for an single name we will have one details list,
That details list will have multiple date lists
And each date list will have multiple values list
{
"_id" : ObjectId("51472e9fd29a736d83c27ca3"),
"name" : "Arun",
"details" : [
{
"date" : "2015-01-17",
"isNew" : false,
"isOld" : true,
"values" : [
{
"money" : "330.0",
"new" : false,
"old" : true,
},
{
"money" : "340.0",
"new" : false,
"old" : true,
}
]
},
{
"date" : "2015-01-17",
"isNew" : false,
"isOld" : false,
"values" : [
{
"money" : "330.0",
"new" : false,
"old" : false,
},
{
"money" : "340.0",
"new" : false,
"old" : false,
}
]
},
{
"date" : "2015-01-17",
"isNew" : true,
"isOld" : false,
"values" : [
{
"money" : "330.0",
"new" : true,
"old" : false,
},
{
"money" : "340.0",
"new" : true,
"old" : false,
}
]
},
{
"date" : "2013-10-19",
"isNew" : true,
"isOld" : false,
"values" : [
{
"money" : "330.0",
"new" : true,
"old" : false,
},
{
"money" : "340.0",
"new" : true,
"old" : false,
}
]
}
]
}
What is need is, i want to SELECT "all the date lists" where "name" : "Arun" and "date" : "2015-01-17",I tried this way and it is not working as expected.I am getting all the dates instead 2015-01-17 in return.
I think only one where condition is working here and that is "name" : "Arun" , Query is not considering "details.date" : "2015-01-17" in where condition.
db.student.find({ "details.date" : "2015-01-17","name" : "Arun" },{"details.date":1}).pretty()
{
"_id" : ObjectId("51472e9fd29a736d83c27ca3"),
"details" : [
{
"date" : "2015-01-17"
},
{
"date" : "2015-01-17"
},
{
"date" : "2015-01-17"
},
{
"date" : "2013-10-19"
}
]
}
I am currently using mongo 1.6.5
Can some one help me to solve this.?
First, you need to upgrade to a current version of MongoDB. 1.6 is now three versions behind the current "major" version.
Second, you need to fix your schema. You say "for an single name we will have one details list" - if you continue adding things into this list/array it will continue growing indefinitely and that's a bad schema design. In addition, it's more correct to group in an array values that you want to fetch together with the document - and in this case you specifically do NOT want to fetch all the values with the document, you only want to fetch an element for a particular date, plus the isOld/isNew fields suggest to me that some of these entries will correspond to out-dated values, and others will be current, and it's a bad idea to lump them together into the same document.
So my recommendation is to change your structure to be multiple documents for each student:
{
"name" : "Arun",
"date" : "2015-01-17",
"isNew" : false,
"isOld" : true,
"values" : [
{
"money" : "330.0",
"new" : false,
"old" : true,
},
{
"money" : "340.0",
"new" : false,
"old" : true,
}
]
},
{
"name" : "Arun",
"date" : "2015-01-17",
"isNew" : false,
"isOld" : true,
"values" : [
{
"money" : "330.0",
"new" : false,
"old" : false,
},
{
"money" : "340.0",
"new" : false,
"old" : false,
}
]
},
{
"name" : "Arun",
"date" : "2015-01-17",
"isNew" : false,
"isOld" : true,
"values" : [
{
"money" : "330.0",
"new" : true,
"old" : false,
},
{
"money" : "340.0",
"new" : true,
"old" : false,
}
]
},
{ "name" : "Arun",
"date" : "2013-10-19",
"isNew" : true,
"isOld" : false,
"values" : [
{
"money" : "330.0",
"new" : true,
"old" : false,
},
{
"money" : "340.0",
"new" : true,
"old" : false,
}
]
}
]
}
Now it'll be much more straight forward to query on various attributes, including being able to query in values as well as outer fields.
Your query is in fact matching both fields. The output is a byproduct of how MongoDB handles arrays. Matching against
"details.date" : "2015-01-17"
will return any documents in the collection where any of the entries from the details field have the right date. It will not just return the individual entries from the details array.
To do this, you may want to look at the $elemMatch operator for projection, to limit the entries in the array that are returned.
Here is your query,
db.sandy.aggregate(
{$unwind : "$details"},
{$match : {"details.date" : "2015-01-17","name" : "Arun"}}
)
And I guess mongo 1.6.5 does not support aggregation. refer to Doc once.
Related
I have the Data/Schema for my student records:
{
"_id" : ObjectId("579ed0ba7d509178a97fae8f"),
"fullName" : "ABC",
"enroll" : "AB1234",
"profile" : {
"isCompleted" : true,
"verification" : [
{
"pro" : true,
"verifiedBy" : "ProAct",
"verifiedOn" : ISODate("2016-09-12T07:36:53.680Z")
},
],
"isChecked" : false,
"fullName" : "ABC",
"gender" : "Male",
"emergencyContactPerson" : {
"name" : "Father",
"mobile" : "9412345678",
"email" : "example#gmail.com",
},
},
"contact" : {
"emailID" : {
"isVerified" : true,
"isChecked" : false,
"verificationTokenExpiresIn" : ISODate("2016-08-01T05:35:00.218Z"),
"verifiedOn" : ISODate("2016-08-01T04:35:10.992Z")
},
"mobileID" : {
"isVerified" : true,
"isChecked" : false,
"verificationTokenExpiresIn" : ISODate("2016-08-01T04:42:45.206Z"),
"verifiedOn" : ISODate("2016-08-01T04:33:36.692Z")
}
},
"services" : [
{
"applied" : true,
"appliedOn" : ISODate("2016-09-17T03:01:49.829Z"),
"status" : "Created",
"mac" : "70-77-88-00-AA-BB",
"createdBy" : "Example"
},
]
}
How can I build query, to get student info with the help of mac address 70-77-88-00-AA-BB. i only know mac address value?
i am new here please help me out
Query
services.mac is an array of all the mac addresses members of services
in querying(not in aggregation $eq) an array is equal with a value if it contains that value, so the above will work
the bellow query returns all the students, that have that mac adrress on the services array
if you want to make it fast you can also create an index on "services.mac"
*read mongodb documentation its very good and with examples
Test code here
db.collection.find({
"services.mac": "70-77-88-00-AA-BB"
})
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 }
})
How to update Single object in array of objects by rules query is that object must by in document that has translation_key == as input that i read and object must have same language (id) if not i must create new object . ( mongodb, mongoose)
Language are required and uniueq in translations
{
"_id" : ObjectId("5bfd5324725fb12bc4863cd8"),
"deleted" : false,
"deleted_at" : null,
"noAuth" : false,
"hidden" : false,
"translation_key" : "Standard",
"translation_type" : "text",
"translation" : [
{
"system" : {
"android" : false,
"ios" : false,
"web" : false,
"api" : false
},
"language" : ObjectId("5bf52e06edb9902e2113d8b3"),
"text":'',
"active" : false,
"prepared_string" : false,
"_id" : ObjectId("5bfd910c2998d929644abd90"),
"params" : []
},
{
"system" : {
"android" : false,
"ios" : false,
"web" : true,
"api" : false
},
"active" : false,
"prepared_string" : false,
"_id" : ObjectId("5bfdb5d22998d929644ac2af"),
"language" : ObjectId("5bf52e06edb9902e6471d8c1"),
"text" : "Standard",
"app_version" : "2.0",
"params" : []
}
],
"create_date" : ISODate("2018-11-27T14:22:28.635Z"),
"update_date" : ISODate("2018-11-27T14:22:28.635Z"),
"__v" : 3
}
Model.findOneAndUpdate(
{
_id: "document_id",
"translation.language": "languageId",
},
{
$set: {
"translation.$.text: "text",
"translation.$.active": "status",
"translation.$.system.android" : true
},
{ new: true, upsert: true, }
)
.lean();
I have this collection
> db.styles.find({"_id":"EP65"}).pretty();
{
"__v" : 6,
"_id" : "EP65",
"colours" : {
"GRYM" : [
{
"on_sale" : false,
"size_code_id" : "XS",
"sku" : "EP65-GRYM0"
},
{
"on_sale" : false,
"size_code_id" : "2XL",
"sku" : "EP65-GRYM5"
}
],
"BLUT" : [
{
"on_sale" : false,
"size_code_id" : "XS",
"sku" : "EP65-BLUT0"
},
{
"on_sale" : false,
"size_code_id" : "X",
"sku" : "EP65-BLUT1"
}
]
}
}
I would like to rename the "on_sale" to "visible", I have about 200 styles each of which has one or many colours.
So basically I want to loop through all the styles collection and for each colour.key rename the "on_sale" to "visible"
any advice is much appreciated
As mentioned in the documentation there is no way to rename fields within arrays. Your only option is to iterate over your collection documents, read them and update each with $unset old/$set new operations.
I have very little experience with Mongo and just cannot seem to get this query to work. I have a document that looks like this:
{
"_id" : ObjectId("51ee8dd79240dfb20a4f823a"),
"value" : {
"population" : false,
"denominator" : false,
"numerator" : false,
"exclusions" : false,
"antinumerator" : false,
"patient_id" : "4fe1ece1a9ffcc03cd000efa",
"first" : "Emilia",
"last" : "Stronger",
"gender" : "F",
"birthdate" : -764708400.0,
"test_id" : null,
"measure_id" : "0024",
"sub_id" : "c",
"effective_date" : 1356930000.0
}
}
I would like to perform a find that looks like this:
{
"value" : {
"denominator" : true,
"measure_id" : "0024",
}
}
But this does not work. If I remove any of the elements of this value object or replace them with wildcards, the find yields zero results.
Any advice would be greatly appreciated.
This should be quite simple:
db.collection.find( { "value.denominator" : true, "value.measure_id" : "0024" } );