Another day. Another Mongodb query.
I wish to create the following structure in once of my collections:
amitverma is the user and the nested object is message's UTC timestamp. I want to push messages in the following structure.
{
"username" : "macbook",
"messages" : {
"amitverma" : {
"1383321755" : {
"to" : "macbook",
"message" : "hi.",
"sender" : "amitverma",
},
"1383321712" : {
"to" : "macbook",
"message" : "hi.",
"sender" : "amitverma",
}
}
},
"_id" : ObjectId("5273d09ab743db7a5f000001")
}
I cant use $push or $addToSet as it isnt an array. Or can I?
Also, I have the following code right now:
var pushNotification = {};
var addon = {};
var anotheraddon = {};
var utcTime = arrayOps.encodeTime();
addon[data.sender] = [];
anotheraddon[utcTime] = data;
addon[data.sender].push(anotheraddon);
// var a = pushNotification;
// a.push(anotheraddon);
// console.log(pushNotification);
pushNotification['messages'] = {}
pushNotification['messages'][data.sender] = [];
pushNotification['messages'][data.sender] = data;
var a = 'messages.' + data.sender + '.$';
console.log('push object');
console.log(pushNotification);
co_notifications.update(
{'username': data.to},
{ $addToSet: pushNotification}, function(err, docs){
console.log(err);
console.log(docs);
if (docs == 0){
co_notifications.insert(
{'username': data.to, 'messages': addon}, function(er, doc){
});
}
},
{upsert: true}
);
Excuse the garbage code. The above code results in this structure:
{
"username" : "macbook",
"messages" : {
"amitverma" : [
{
"1383321755" : {
"to" : "macbook",
"message" : "hi.",
"sender" : "amitverma",
}
}
]
},
"_id" : ObjectId("5273d09ab743db7a5f000001")
}
which isn't exactly what I desire.
Is there a way I can create the structure I want and also read and update from the same easily? Thanks.
You can insert additional elements of the form you outlined above to
an existing document by using the following update:
info = {"to": "...", "message": "...", "sender": "..."}
c.update({}, {$set: {'messages.amitverma.1111111111': info}})
After executing this update on your example document the result is:
{
"_id" : ObjectId("5273d09ab743db7a5f000001"),
"messages" : {
"amitverma" : {
"1111111111" : {
"to" : "...",
"message" : "...",
"sender" : "..."
},
"1383321712" : {
"to" : "macbook",
"message" : "hi.",
"sender" : "amitverma"
},
"1383321755" : {
"to" : "macbook",
"message" : "hi.",
"sender" : "amitverma"
}
}
},
"username" : "macbook"
}
You don't say what kind of queries you want to do, but here's an
example that shows the kind of thing you might do. This query finds a
document with a give username, and uses a projection to return only a
specific subset of the document, in this example the element that we just
added:
c.findOne({username:'macbook'}, {'messages.amitverma.1111111111':1})
This query produces the following result:
{
"_id" : ObjectId("5273d09ab743db7a5f000001"),
"messages" : {
"amitverma" : {
"1111111111" : {
"to" : "...",
"message" : "...",
"sender" : "..."
}
}
}
}
Hope this helps,
Bruce
Related
I have this data structure
{
"job-requests" : {
"pending" : {
"-KkyZGfqmiIVryyLAZpD" : {
"job_details" : "asd",
"job_type" : "Repair Required",
"location" : "123",
"location_lat" : 14.164633210106128,
"location_lng" : 121.24110514763743,
"timestamp" : 1495698316411
}
}
},
"office-info" : {
"123" : {
"office_acronym" : "123",
"office_contact_number" : "123-1234",
"office_current_head" : "None",
"office_name" : "123",
"office_parent_unit" : "123"
}
},
"office-location-list" : {
"123" : {
"location_lat" : 14.164633210106128,
"location_lng" : 121.24110514763743
}
},
"users" : {
"MBR5o37xafUyuLw14Xqa1ku0Zui1" : {
"designation" : "staff",
"email" : "123#asd.com",
"given_name" : "23",
"last_name" : "123",
"password" : "1234567",
"timestamp" : 1495617328793
},
"Nwacy3ADczgLC85OvSAgUNEGMkx2" : {
"designation" : "staff",
"email" : "adsasd#asdas.com",
"given_name" : "122123",
"last_name" : "12",
"password" : "asdasdsadasd",
"timestamp" : 1495681430048
}
}
}
I will be needing the keys [pending, active, finished] along with the data of the newly added child. This is how I accessed Firebase
firebase.database ().ref ('job-requests').on ('child_added', (snapshot) => {
console.log (snapshot.key); // prints out [pending, active, finished]
console.log (snapshot.val()); // prints out an object
});
It prints this on the console:
I tried using JSON.parse (), snapshot.child (path), snapshot.field, and snapshot[field] but errors are thrown out. How do I do this?
Your code gets all job requests. Since those are in a hierarchy by their state, your code will need to handle this:
firebase.database ().ref ('job-requests').on ('child_added', (snapshot) => {
snapshot.forEach((stateSnapshot) => {
console.log(stateSnapshot.key); // 'pending', etc
stateSnapshot.forEach((jobSnapshot) => {
console.log(jobSnapshot.key);
console.log(jobSnapshot.val());
});
});
});
I have 2 bi-directional models and I use JsonIdentityInfo to prevention from infinite Recursion in json result. Here is my viewmodels:
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class GroupsViewModel extends BaseEntityViewModel<Long> {
private String title;
private Set<UserViewModel> users;
}
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class UserViewModel extends BaseEntityViewModel<Long> {
private String username;
private String password;
private Set<GroupsViewModel> groups;
}
and a part of my json result is like below:
[{
"id" : 1,
"title" : "adminGroup",
"users" : [{
"id" : 1,
"username" : "admin",
"password" : "...",
"groups" : [1]
}, {
"id" : 31,
"username" : "user78",
"password" : "...",
"groups" : [1]
}, {
"id" : 3,
"username" : "ali",
"password" : "...",
"groups" : [{
"id" : 2,
"title" : "newsWriterGroup",
"users" : [{
"id" : 14,
"username" : "staff1",
"password" : "...",
"groups" : [{
"id" : 1005,
"title" : "FileManagerAccessGroup",
"users" : [{
"id" : 25,
"username" : "test1",
"password" : "...",
"groups" : [1005, {
"id" : 1006,
"title" : "noAccessGroup",
"users" : [25, {
"id" : 26,
"username" : "test5",
"password" : "...",
"groups" : [1006]
}
]
}
]
}, 14]
}, 2]
}, ...
As shown in above, if object is repetitive in json result, Jackson put only it's identifier of it. Now I want to know Is there any javascript/jquery library to represent json-result of #JsonIdentityInfo? for example, when javascript/jquery library arrive at 1005 identifier , it automaticaly load group object with id = 1005.
It's very unlikely that such a targeted library exists. You could easily write a function though that deconstructs the data back into an array of users and groups by using typeof checking, and then using recursion when a new object is encountered in the groups or users attributes.
Just be careful when printing out the results that you don't create a circular reference. See this question for help on that.
function Group(group) {
this.id = group.id;
this.title = group.title;
this.users = [];
Group.cache[this.id] = this;
group.users.forEach(this.addUser, this);
}
Group.cache = {};
Group.prototype.addUser = function(user) {
this.users.push(
typeof user === 'number'
? User.cache[user]
: new User(user)
);
};
function User(user) {
this.id = user.id;
this.username = user.username;
this.password = user.password;
this.groups = [];
User.cache[this.id] = this;
user.groups.forEach(this.addGroup, this);
}
User.cache = {};
User.prototype.addGroup = function(group) {
this.groups.push(
typeof group === 'number'
? Group.cache[group]
: new Group(group)
);
};
// begins the recursion
JSON.parse(
'[{"id":1,"title":"adminGroup","users":[{"id":1,"username":"admin","password":"...","groups":[1]},{"id":31,"username":"user78","password":"...","groups":[1]},{"id":3,"username":"ali","password":"...","groups":[{"id":2,"title":"newsWriterGroup","users":[{"id":14,"username":"staff1","password":"...","groups":[{"id":1005,"title":"FileManagerAccessGroup","users":[{"id":25,"username":"test1","password":"...","groups":[1005]},14]},2]},3]},1]}]}]'
).forEach(function(group) { new Group(group) });
function stopCircularWithId(key, value) {
return key === 'users' || key === 'groups'
? value.map(function(u) { return u.id })
: value;
}
console.log('groups:', JSON.stringify(Group.cache, stopCircularWithId, 4));
console.log('users:', JSON.stringify(User.cache, stopCircularWithId, 4));
JSFiddle
My database looks like
{
"chats" : {
"-K5hUtxNOPLWwRTb8fAj" : {
"clientId" : 893,
"messages" : {
"-K5hUtyCwWuPeFT0cSXr" : {
"chatKey" : "-K5hUtxNOPLWwRTb8fAj",
"messageText" : "new message",
"timestamp" : 1450314801055,
"userId" : "19eaa3f0-4ab3-44b4-b418-03b64ca2313a"
},
"-K5hUvwKsAOvuvt-ymFG" : {
"chatKey" : "-K5hUtxNOPLWwRTb8fAj",
"messageText" : "did this work",
"timestamp" : 1450314809127,
"userId" : "48f7a208-5647-4d0e-921c-c49595de1db2"
}
},
"newQuestion" : false,
"startedByUserId" : "19eaa3f0-4ab3-44b4-b418-03b64ca2313a"
},
"-K5hVKjs4SkSHD7WTh1I" : {
"clientId" : 518,
"messages" : {
"-K5hVNzPKNgxLCgkfInI" : {
"chatKey" : "-K5hVKjs4SkSHD7WTh1I",
"messageText" : "this is new",
"timestamp" : 1450314928109,
"userId" : "19eaa3f0-4ab3-44b4-b418-03b64ca2313a"
}
},
"newQuestion" : true,
"startedByUserId" : "19eaa3f0-4ab3-44b4-b418-03b64ca2313a"
}
}
}
How can I get all chats that have a newQuestion set to true? I've tried a few different queries, the latest is:
firebaseDb.child("chats/newQuestion").equalTo(true).once("value"...
But that complains about an order being needed for a boolean?
You have to specify an orderBy method first.
var query = firebaseDb.child("chats").orderByChild("newQuestion").equalTo(true);
Here's the Firebase docs on querying.
I am trying to run a set of java script and update command using by php mongo execute command:
$pSsId = '123456789';
$pUid = 14;
$pRowID = '6fce077519d838bb8ed401448dae6e3a';
$pKey = 'name';
$pValue = 'King Kobra';
$response = $db()->execute("
function(pSsid, pUid, pRowid, pKey, pValue){
udocs = db.VizSpreadsheet.findOne({'_id' : pSsid, 'data.uid' : pUid }).data;
posU = udocs.map(function(d) { return d.uid; }).indexOf(pUid);
posR = udocs[posU].rows.map(function(r) { return r.row_id; }).indexOf(pRowid);
var setCriteria = {};
setCriteria['_id'] = pSsid;
setCriteria['data.uid'] = pUid;
var setObject = {};
setObject['data.'+posU+'.'+'rows'+'.'+posR+'.'+pKey] = pValue;
db.VizSpreadsheet.update(
{
setCriteria
},
{
'$set': setObject
}
);
}", array($pSsId, $pUid, $pRowID, $pKey, $pValue));
But the result is error
Array ( [errmsg] => exception: can't have . in field names [data.1.rows.0.2#12#07337187ee7e48f92ed1689b22d7ed77] at src/mongo/shell/collection.js:155 [code] => 16722 [ok] => 0 )
The collection will look like this
"_id" : "123456789",
"data" : [
{
"uid" : 12,
"rows" : [
{
"row_id" : "8979afefedb42aa8c62e9baa83e35ba0",
"updated_by" : "12",
"updated_at" : "1428644989",
"name" : "AAAAAAAAAAA"
},
{
"row_id" : "7415f767c62a84173d1dcf82ad1d809d",
"updated_by" : "12",
"updated_at" : "1428644989",
"name" : "BBBBBBBBBBBBB"
}
]
},
{
"uid" : 14,
"rows" : [
{
"row_id" : "21b1120811cfe893486e9e9afbebb660",
"updated_by" : "12",
"updated_at" : 1428644989,
"name" : "CCCCCCCCCC"
},
{
"row_id" : "6fce077519d838bb8ed401448dae6e3a",
"updated_by" : "12",
"updated_at" : 1428644841,
"names" : "DDDDDDDDDDD"
}
]
}
What i am trying is to update "name" field of second element in "rows" array for "uid" = 14. The data is updated by '$set' method and specifying the element position which is find by javascript code.
The same code executed successfully in shell.
But in php it fails to detect the position operator.
As an error message says, you cannot use . (dots) within your data.
Try separate your 'subfields' with : for example:
setObject['data:'+posU+':'+'rows'+':'+posR+':'+pKey] = pValue;
I am new to javascript.
I want to have an object with this structure.
Users = {
User1 : {
"name" : "name",
"id" : "123"
}
User2 : {
"name" : "name",
"id" : "123"
}
}
so I should define Users like this:
var Users = {};
How can I add new User to Users? and How can I read and write from users inside Users object like this:
// reading
User1_name = Users.User1.name;
// writing
Users.User1.name = "new name";
Your code is fine (except the missing comma #Philipp pointed), but you can use an array too:
var users = [
{
"name" : "name",
"id" : "123"
},
{
"name" : "name",
"id" : "123"
}
];
var userName = users[0].name;
users[0].name = "new name";
You can define users like this, you are just missing a comma
Users = {
User1 : {
"name" : "name",
"id" : "123"
} <--
User2 : {
"name" : "name",
"id" : "123"
}
}
Should be ( with var added for clarity )
var Users = {
User1 : {
"name" : "name",
"id" : "123"
},
User2 : {
"name" : "name",
"id" : "123"
}
}
Reading and writing can be done the way you described.
To add a new user, you could do something like this
Users["User3"] = {
"name" : "name3",
"id" : "1234"
}