I am making a web app. Currently I am storing the messages inside messages columns like below.
I have a column called msges and I have messages as time as key and value details. I want to create a function in which I pass the time, It will return the details of it. Can anyone help me? I can get single field but I don't know how to get it through key value. This is my function.
function getMessageDetails(uname,time,callback){
global.users.find({"uname" : uname,"msges":time},
// {"friends.friendUname":1,_id:0},
{_id:0},
function(err,doc){
if(err){
callback(false,err,"Message not found.",null);
}else{
callback(true,null,"",doc);
}
}
);
}
Thanks in advance. :)
I'd personally try to model your data a bit diffrently, If you had:
{
_id: "123123",
//...
friends: [
{ friendName: "etc..."}
],
msges : [
{
time: "16:25:02",
from: "alizia",
title : "hi buddy",
read: true
},
{
time: "12:25:02",
from: "bob",
title : "hi bobby",
read: false
}
]
}
You'd be able to query the following data by:
db.users.find({_id: "123123", "msges.time" : "16:25:02"}, { "msges.$.from" : 1 })
and will just pull out the one msg based on the query:
{
"_id" : "123123",
"msges" : [
{
"time" : "16:25:02",
"from" : "alizia",
"title" : "hi buddy",
"read" : true
}
]
}
Related
I am the beginner of the MongoDB
Here I mentioned my database schema
{
"_id" : ObjectId("5e72067973c1241068a13647"),
"client_id" : "1001",
"dependent" : [
{
"dependent_name" : "asdsa",
"dependent_id" : "DE100"
},
{
"dependent_name" : "fdggd",
"dependent_id" : "DE101"
}
]
}
I want to add new field based on client_id and dependent_id
Here I mentioned My query but cannot able to get my expected result
db.collection.update({"client_id" : "1001","dependent.dependent_id":"DE101"}, {"$push": {"reason":"expired"}})
I am Expected Result is
{
"_id" : ObjectId("5e72067973c1241068a13647"),
"client_id" : "1001",
"dependent" : [
{
"dependent_name" : "asdsa",
"dependent_id" : "DE100"
},
{
"dependent_name" : "fdggd",
"dependent_id" : "DE101",
"reason":"expired"
}
]
}
so anyone help me to solve this
db.collection.update({"client_id" : "1001","dependent.dependent_id":"DE101"},
{$set:
{"dependent.$.reason":"expired"}})
Try this it works for me using $
As i am also new to mongodb, as i tried, i can give you suggestion to update whole document or replace it.
both way i tried, and query is as below.
Update
db.updateColl.update({ 'dependent.dependent_id': 'DE101' },
{
$set: {
"dependent": [
{
"dependent_name": "asdsa",
"dependent_id": "DE100"
},
{
"dependent_name": "fdggd",
"dependent_id": "DE101",
"reason": "expired"
}
]
}
});
Replace
db.updateColl.replaceOne({ 'dependent.dependent_id': 'DE101' }, {
"dependent": [
{
"dependent_name": "asdsa",
"dependent_id": "DE100"
},
{
"dependent_name": "fdggd",
"dependent_id": "DE101",
"reason": "expired"
}
]
})
may be it can help you. if any suggestion regarding it wellcome.
Below the data structure of my services in MongoDB:
"serviceInfo" : {
"title" : "Lorem ipsum",
"options" : [
{
"startDate" : ISODate("2018-10-01T00:00:00.000Z"),
"endDate" : ISODate("2018-10-31T00:00:00.000Z"),
"availabilities" : [
{
"businessDay" : {
"id" : 1,
"name" : "Monday"
},
}
]
}
]
Now, I want to query all the services available the Monday during the period between startDate and endDate.
I tried this code but I have an empty array as result instead of my document.
db.collection('services').find({
'serviceInfo.options': {
$elemMatch: {
'startDate': { $lte: new Date(req.query.date) },
'endDate': { $gte: new Date(req.query.date) },
'availabilities': {
$elemMatch: {
'businessDay.id': req.query.day
}
}
}
}
}).toArray()
I guess my problem is in the nested array availabilities but I don't find the correct way to do the query.
Thanks in advance for your help.
I found my problem.
'businessDay.id' expected an Int32 and parseInt(req.query.day) did the trick.
Followup Question
Thanks #4J41 for your spot on resolution. Along the same lines, I'd also like to validate one other thing.
I have a mongo document that contains an array of Strings, and I need to convert this particular array of strings into an array of object containing a key-value pair. Below is my curent appraoch to it.
Mongo Record:
Same mongo record in my initial question below.
Current Query:
templateAttributes.find({platform:"V1"}).map(function(c){
//instantiate a new array
var optionsArray = [];
for (var i=0;i< c['available']['Community']['attributes']['type']['values'].length; i++){
optionsArray[i] = {}; // creates a new object
optionsArray[i].label = c['available']['Community']['attributes']['type']['values'][i];
optionsArray[i].value = c['available']['Community']['attributes']['type']['values'][i];
}
return optionsArray;
})[0];
Result:
[{label:"well-known", value:"well-known"},
{label:"simple", value:"simple"},
{label:"complex", value:"complex"}]
Is my approach efficient enough, or is there a way to optimize the above query to get the same desired result?
Initial Question
I have a mongo document like below:
{
"_id" : ObjectId("57e3720836e36f63695a2ef2"),
"platform" : "A1",
"available" : {
"Community" : {
"attributes" : {
"type" : {
"values" : [
"well-known",
"simple",
"complex"
],
"defaultValue" : "well-known"
},
[......]
}
I'm trying to query the DB and retrieve only the value of defaultValue field.
I tried:
db.templateAttributes.find(
{ platform: "A1" },
{ "available.Community.attributes.type.defaultValue": 1 }
)
as well as
db.templateAttributes.findOne(
{ platform: "A1" },
{ "available.Community.attributes.type.defaultValue": 1 }
)
But they both seem to retrieve the entire object hirarchy like below:
{
"_id" : ObjectId("57e3720836e36f63695a2ef2"),
"available" : {
"Community" : {
"attributes" : {
"type" : {
"defaultValue" : "well-known"
}
}
}
}
}
The only way I could get it to work was with find and map function, but it seems to be convoluted a bit.
Does anyone have a simpler way to get this result?
db.templateAttributes.find(
{ platform: "A1" },
{ "available.Community.attributes.type.defaultValue": 1 }
).map(function(c){
return c['available']['Community']['attributes']['type']['defaultValue']
})[0]
Output
well-known
You could try the following.
Using find:
db.templateAttributes.find({ platform: "A1" }, { "available.Community.attributes.type.defaultValue": 1 }).toArray()[0]['available']['Community']['attributes']['type']['defaultValue']
Using findOne:
db.templateAttributes.findOne({ platform: "A1" }, { "available.Community.attributes.type.defaultValue": 1 })['available']['Community']['attributes']['type']['defaultValue']
Using aggregation:
db.templateAttributes.aggregate([
{"$match":{platform:"A1"}},
{"$project": {_id:0, default:"$available.Community.attributes.type.defaultValue"}}
]).toArray()[0].default
Output:
well-known
Edit: Answering the updated question: Please use aggregation here.
db.templateAttributes.aggregate([
{"$match":{platform:"A1"}}, {"$unwind": "$available.Community.attributes.type.values"},
{$group: {"_id": null, "val":{"$push":{label:"$available.Community.attributes.type.values",
value:"$available.Community.attributes.type.values"}}}}
]).toArray()[0].val
Output:
[
{
"label" : "well-known",
"value" : "well-known"
},
{
"label" : "simple",
"value" : "simple"
},
{
"label" : "complex",
"value" : "complex"
}
]
/* 0 */
{
"_id" : ObjectId("55addc2f8dab32aca87ce0bd"),
"partNum" : "part1",
"dest" : "First Part",
"sales" : [
"sale1",
"sale2",
"sale3"
],
"salesData" : {
"sale1" : {
"mcode" : "mc11",
"dtype" : [
"AAA",
"BBB"
]
}
}
}
/* 1 */
{
"_id" : ObjectId("55addc408dab32aca87ce0be"),
"partNum" : "part2",
"dest" : "Second Part",
"sales" : [
"sale1",
"sale2",
"sale3"
],
"salesData" : {
"sale1" : {
"mcode" : "mc22",
"dtype" : [
"AAA",
"BBB"
]
}
}
}
I am not that much efficient in writing mongo script. My requirement is to append one more value to "dtype" array wherever "mcode" is "mc11" in all of the documents inside the collection. Above is the two document output from my collection. I was using the below script to do it and its not working. Can anyone please help me
db.testingRD.find().forEach( function(myDocument)
{
db.testingRD.update({id: myDocument._id}, {$push : {"salesData.sale1.dtype" : "DDD"}});
});
To append one more value to "dtype" array wherever "mcode" is "mc11", use the following update where the query object is the selection criteria for the update and is the same query selector as in the find() method, the update object has the $push modifications to apply and then the options document which is optional. If that is set to true, it updates multiple documents that meet the query criteria:
var query = { "salesData.sale1.mcode": "mc11" },
update = {
"$push": { "salesData.sale1.dtype": "DDD" }
},
options = { "multi": true };
db.testingRD.update(query, update, options);
You had a typing mistake in the script (you forgot an underscore):
db.testingRD.find().forEach( function(myDocument)
{
db.testingRD.update({_id: myDocument._id}, {$push : {"salesData.sale1.dtype" : "DDD"}});
});
I always use a trick when an update seams to not working: I change the update with a printjson + find so that I can see if it is matching anything:
db.testingRD.find().forEach( function(myDocument) { printjson(db.testingRD.find({_id: myDocument._id})) } );
Similar to this question
Barrowing the data set, I have something similar to this:
{
'user_id':'{1231mjnD-32JIjn-3213}',
'name':'John',
'campaigns':
[
{
'campaign_id':3221,
'start_date':'12-01-2012',
},
{
'campaign_id':3222,
'start_date':'13-01-2012',
}
]
}
And I want to add a new key in the campaigns like so:
{
'user_id':'{1231mjnD-32JIjn-3213}',
'name':'John',
'campaigns':
[
{
'campaign_id':3221,
'start_date':'12-01-2012',
'worker_id': '00000'
},
{
'campaign_id':3222,
'start_date':'13-01-2012',
'worker_id': '00000'
}
]
}
How to insert/update a new key into an array of objects?
I want to add a new key into every object inside the array with a default value of 00000.
I have tried:
db.test.update({}, {$set: {'campaigns.worker_id': 00000}}, true, true)
db.test.update({}, {$set: {campaigns: {worker_id': 00000}}}, true, true)
Any suggestions?
I'm supposing that this operation will occur once, so you can use a script to handle it:
var docs = db.test.find();
for(var i in docs) {
var document = docs[i];
for(var j in document.campaigns) {
var campaign = document.campaigns[j];
campaign.worker_id = '00000';
}
db.test.save(document);
}
The script will iterate over all documents in your collection then over all campaigns in each document, setting the *worker_id* property.
At the end, each document is persisted.
db.test.update({}, {$set: {'campaigns.0.worker_id': 00000}}, true, true
this will update 0 element.
if you want to add a new key into every object inside the array you should use:
$unwind
example:
{
title : "this is my title" ,
author : "bob" ,
posted : new Date() ,
pageViews : 5 ,
tags : [ "fun" , "good" , "fun" ] ,
comments : [
{ author :"joe" , text : "this is cool" } ,
{ author :"sam" , text : "this is bad" }
],
other : { foo : 5 }
}
unwinding tags
db.article.aggregate(
{ $project : {
author : 1 ,
title : 1 ,
tags : 1
}},
{ $unwind : "$tags" }
);
result:
{
"result" : [
{
"_id" : ObjectId("4e6e4ef557b77501a49233f6"),
"title" : "this is my title",
"author" : "bob",
"tags" : "fun"
},
{
"_id" : ObjectId("4e6e4ef557b77501a49233f6"),
"title" : "this is my title",
"author" : "bob",
"tags" : "good"
},
{
"_id" : ObjectId("4e6e4ef557b77501a49233f6"),
"title" : "this is my title",
"author" : "bob",
"tags" : "fun"
}
],
"OK" : 1
}
After you could write simple updaiting query.