Mongo Update Query is not working properly - javascript

I have the data in one collection in the format given below
{
"tenantId":"Hello",
"timings":[{
"name":"Hi",
"category":"standard",
"pickAndPack":30,
"type":"pickup"
},
{
"name":"Hi",
"category":"premium",
"pickAndPack":30,
"type":"pickup"
}]
}
I want to update the data inside timings array.But its not working as expected.
Expected Output
{
"tenantId":"Hello",
"timings":[{
"name":"Hi",
"category":"standard",
"pickAndPack":30,
"type":"pickup"
},
{
"name":"Hello",
"category":"premium",
"pickAndPack":1200,
"type":"pickup"
}]
}
I have tried this query
let dataExists = [{
"name":"Hi",
"category":"standard",
"pickAndPack":30,
"type":"pickup"
},
{
"name":"Hello",
"category":"premium",
"pickAndPack":1200,
"type":"pickup"
}
masterdb.collection('corporate').update({ tenantId ,'timings.type': type}, { $set: { 'timings.$': dataExists } });```

Related

Is there any way to compare an array in mongo aggregate?

This code does not match the bu.subUser with subUser and due to mismatch nothing is returned. How to achieve the output?
{
$match: {
subUser: {
$ne: blockedUsers.map((bu) => {
return bu.subUser;
}),
},
},
}
{ $match: { subUser: { $nin: blockedUsers.map((bu) => bu.subUser) } } }

Immutability-helper - How to update this value?

I have a JSON object stored in "aggRequest", this is my JSON
{
"state":{
"controllerStates":[
],
"rulesetStates":[
{
"rulesetContext":{
"dialog_stack":[
{
"dialog_node":"root"
}
],
"dialog_turn_counter":1,
"dialog_request_counter":1,
"_node_output_map":{
"node_1_1504607088493":[
0
]
},
"branch_exited":true,
"branch_exited_reason":"completed"
},
"convId":"XXXX",
"modelRef":"XXXX"
}
],
"selfCallCount":0,
"sysTurnCount":2,
"userTurnCount":2
},
"context":{
"conversationContext":{
"brand":"XXXX",
"channel":"XXX"
},
"userData":{
"tokens":[
]
}
},
"XXXXX":"2.0",
"XXXXX":"XXXXX",
"XXXXX":"XXXXX",
"XXXXX":"XXXXX",
"XXXXX":"XXXXX",
"turnStart":"2018-08-10T15:21:36.075Z",
"turnEnd":"2018-08-10T15:21:36.076Z"
}
I am trying to set the turnEnd to a new date using moment, the date is being created correctly, and I believe my function is correct:
const update = require('immutability-helper');
function updatePropertyValue() {
const momentDateChange = getRunDateAsString();
update(aggRequest, {
$set:
{
turnEnd: `${momentDateChange}`,
},
});
console.log(aggRequest)
}
When I view the addRequest console.log, the date has not been updated. Why would that be?
The whole idea of immutability is that you can not change the data. Instead you creating a new one. Like in the example below:
const update = require('immutability-helper');
const data = {
"turnEnd":"2018-08-10T15:21:36.076Z"
};
const newData = update(data, { $set: { turnEnd: 'voala!' } });
console.log(data); // it is immutable, right?
console.log(newData); // it is new version of the data
In order to solve the issue change your code to use updated (new version) of your data:
const updateAggRequest = update(aggRequest, { $set: { turnEnd: momentDateChange } });

Query the ids of every entry including a specified child key

Given a database scheme like the following:
{
"lessons": {
"subjectId1": {
"lessonId2": { ... },
"lessonId4": { ... },
"lessonId6": { ... }
},
"subjectId2": {
"lessonId1": { ... },
"lessonId3": { ... },
"lessonId5": { ... },
"lessonId7": { ... }
}
}
}
How do I retrieve the id(s) of any subject(s) that include a given lessonId?
I came up with a function like this:
const refWithParent = database.ref("lessons");
const snapshot = await refWithParent.orderByChild(lessonId).limitToLast(1).once("value");
let firebaseId = null;
if (snapshot.val() !== null) {
snapshot.forEach(entry => {
firebaseId = entry.key;
return true;
});
}
return firebaseId;
This does work but I can't create an index in the database as the children are dynamically created.
Is there any easier way to retrieve the id?
As I understood you want to retrieve one index of any subject that contains a lesson with a specific id. If so, you can add a node "contains" to each subject into which you will put a key/value of the form: lessonId: true.
{
"lessons":{
"subjectId1":{
"contains":{
"lessonId2":true,
"lessonId4":true,
"lessonId6":true
},
"lessonId2":{ ... },
"lessonId4":{ ... },
"lessonId6":{ ... }
},
"subjectId2":{
"contains":{
"lessonId1":true,
"lessonId3":true,
"lessonId5":true,
"lessonId7":true
},
"lessonId1":{ ... },
"lessonId3":{ ... },
"lessonId5":{ ... },
"lessonId7":{ ... }
}
}
}
And then make a query (assuming lessonID is a variable in your code):
refWithParent.orderByChild(`contains/${lessonID)`).equalTo(true).limitToFirst(1).once('value');
and then check the obtained snaphost as follows:
if (snapshot.val() !== null)
{
let subjectId = snapshot.key;
//TODO something with subjectId...
}
Note, you must always add corresponding pair to "contains" node when you add a lesson to a subject. The same with removing.
P.S. If you want to obtain IDs of all subjects that contain given lesson, then simply remove .limitToFirst(1) from the query. That's all.
In Nosql like firebase you can denormalise or form your database as you want. I would advise that you make all your lesson names have a concatenation of it's subject when you creating them in order to avoid your querying of the database.
The codes below can help in getting a unique lesson id with a concatenation of the subject name before you create them.
let newId = database.ref("lessons").ref.push().key; //<-- get a new unique id
let newlessonname = 'Subject2_' + newId;
So your db would look like this
{
"lessons": {
"subjectId1": {
"subjectId1_lessonId2": { ... },
"subjectId1_lessonId4": { ... },
"subjectId1_lessonId6": { ... }
},
"subjectId2": {
"subjectId2_lessonId1": { ... },
"subjectId2_lessonId3": { ... },
"subjectId2_lessonId5": { ... },
"subjectId2_lessonId7": { ... }
}
}
}
Alternatively
You can include your Subjectid in the object of each lesson like this
{
"lessons": {
"subjectId1": {
"lessonId2": {subjectid:"subjectId1" ... },
"lessonId4": { ... },
"lessonId6": { ... }
},
"subjectId2": {
"lessonId1": { ... },
"lessonId3": { ... },
"lessonId5": { ... },
"lessonId7": { ... }
}
}
}

Node.js: How do I $pull from an array of $oid in Mongo/Mongoose?

I'm trying to remove an object from an array of $oid from within a single document with mongoose using update.
Here is a hypothetical schema based on the schema I'm using now:
var TestSchema = Schema({
name: { type: String },
otherRefs: [ {type: Schema.ObjectId, ref: 'OtherSchema' } ]
});
An example document would look like (note: these aren't actual ObjectIDs from my db - I just randomly typed them in to give an idea of what the document would look like - the documents in my actual db have valid $oid values:
{ "_id" : { "$oid" : "56da0b6326008d0c24a4f029" },
"name" : "name1",
"otherRefs" : [
{"$oid" : "56c340259402505c2720541b"},
{"$oid" : "56c340259402505c2720541e"},
{"$oid" : "56c340259402505c2720541f"},
{"$oid" : "56d758862494c411001ca603"}
]
}
Here is the query I'm trying to use:
TestSchema.update(
{ '_id': testResult._id },
{ $pull: { 'otherRefs': { $oid : mongoose.Schema.ObjectId( refResult._id ) } } },
false,
true,
function(err, success) {
if (err) {
res.json(err);
} else {
res.json('success', success);
}
}
)
Have also tried { $pull: { 'otherRefs': refResult._id } } with no success.
testResult._id and refResult._id are received from previous queries.
Been at this for a while now and can't seem to wrap my head around this problem. Hoping someone can help me figure out what I'm doing wrong.
Thanks!
EDIT:
Now using:
TestSchema.update(
{ '_id': testResult._id },
{ $pull: { 'otherRefs': refResult._id ) } },
function(err, success) {
if (err) {
console.log(err);
} else {
console.log('Success');
}
}
)
The query doesn't hang anymore and "Success" is getting logged but nothing is changed in the actual document in DB.

Update field in Object array in Meteor (mongoDB)

I have the following document:
{
"gameName":"Shooter",
"details":[
{
"submitted":1415215991387,
"author":"XYZ",
"subPlayer":{
"members":{
"squad1":[
{
"username":"John",
"deaths":0
}
]
},
"gameSlug":"0-shooter"
}
}
],
"userId":"foL9NpoZFq9AYmXyj",
"author":"Peter",
"submitted":1415215991608,
"lastModified":1415215991608,
"participants":[
"CXRR4sGf5AdvSjdgc",
"foL9NpoZFq9AYmXyj"
],
"slug":"1-shooterConv",
"_id":"p2QQ4TBwidjeZX6YS"
}
... and the following Meteor method:
Meteor.methods({
updateDeaths: function(gameSlug, user, squad) {
Stats.update({details.subPlayer.gameSlug: gameSlug}, ...}); // ???
}
});
My goal is to update the field deaths. The method has the argument user which is the user object (username = user.username). Furthermore, the argument squad is the squad name as string, e.g. squad1.
How can I do this?
Any help would be greatly appreciated.
You should use something like this:
db.collection.update(
{'userId':'foL9NpoZFq9AYmXyj', 'details.subPlayer.gameSlug':'0-shooter'},
{'$set':
{'details': [{
'subPlayer': {
'members': {
'squad1':[{'username':'John','death':1}]
}
}
}]
}
}
)
UPD:
Also, maybe a better way is to use find().snapshot().forEach(). But I don't know how Meteor supports it. Example:
Stats.find({'userId':'foL9NpoZFq9AYmXyj', 'details.subPlayer.gameSlug':'0-shooter' }).map(function (e) {
e.details.forEach(function (d) {
var squad = 'squad1';
d.subPlayer.members[squad].forEach(function (s) {
s.deaths = 10000;
});
});
Stats.update({'_id': e._id}, e);
});

Categories