Complete child field with parent field on mongodb - mongodb

enter image description hereI have this problem that I need to complete a child field with a value that already exists on parent field, like this:
{
"title":"learning mongo",
"description":"how to add child field",
"createdAt":"2020-04-25 09:19:28.285Z"
"user":{
"name":"John",
"email":"john#gmail.com"
}
}
And I'm writing a script that must use the createdAt value inside user, as below:
{
"title":"learning mongo",
"description":"how to add child field",
"createdAt":"2020-04-25 09:19:28.285Z"
"user":{
"name":"John",
"email":"john#gmail.com",
"joinedAt":"2020-04-25 09:19:28.285Z"
}
}
I'm using kotlin and mongock-spring-v5 and I wrote this code to do this migration:
#ChangeSet(id = "addUserJoinedAtField", author = "Paulo", systemVersion = "2.7.0", order = "047")
fun addUserJoinedAtField(mongoTemplate: MongockTemplate) {
val update = Update().set("users.$[user].joinedAt", "createdAt").filterArray(Criteria.where("user.joinedAt").exists(false));
mongoTemplate.updateMulti(Query(), update, PROJECT_COLLECTION)
}
But when I do this, the result is the field "joinedAt":"createdAt" added to the user. How do I pick up the createdAt value instead?
my attempts and the following results

Related

How to build a JSON object in select query in Objection.js

I have a "location" jsonb type column in table "Ads". It stores values like these:
{"lat": 33.742001,
"lng": -117.823639,
"zip": "92780",
"city": "Tustin",
"state": "CA"}
How would I write a select query in Objection.js that returns the same location object with only the "city" property in it. I need something like:
const ads = AdModel.query().select([
...
? // <- need the result to be {location: {city: "Tustin"}}
])
Basically, I need to build {location: city: ...} object and fill in the city name.
Add the $parseDatabaseJson to parse the location field
class Ads extends Model {
static get tableName() {
return 'Ads';
}
$parseDatabaseJson(json) {
json = super.$parseDatabaseJson(json);
let location = json.location;
if(location){
location = JSON.parse(location)
}
return Object.assign({}, json,{ location });
}
}
add the map for selecting specific field
Ads.query()
.select('location')
.map((data)=>data.location.city)
.then((city)=>console.log(city));
I was actually able to build the JSON object I need as such inside .select([...]) method:
raw("json_build_object('city', ??.location->'city') as location", ['Ads'])

How can I retrieve data with queryEqualToValue in auto id child. Firebase-iOS

As my question. I can't retrieve data from firebase when I try to use "queryEqualToValue" with auto id key.
self.ref.child(..my child..).queryOrderByChild("name").queryEqualToValue("my name")
auto child id above child "name".
Edit: for my json tree
Students
(auto id)
name
first name
nick name
My real data doesn't like this but this's for example structure.
I really want to check equal to "first name".
Here's my code
let ref = FIRDatabase.database().reference()
ref.child("Students").queryOrderedByChild("name").queryEqualToValue("Jason bourne").observeEventType(.Value, withBlock: { snapshot in
print("value : " + snapshot.value)
}
Given your realtime database looks something like this:
{
"students": {
1: {
"name": {
"first_name": "Nathapong",
"nick_name": "Oniikal3"
}
}
}
}
You can observe the students path with the event type ChildAdded and order the query by child key name/first_name. Then you can use queryEqualToValue to find students with a particular first name.
let ref = FIRDatabase.database().referenceWithPath('students').queryOrderByChild("name/first_name").queryEqualToValue("Nathapong")
ref.observeSingleEventOfType(.ChildAdded, block: { snapshot in
print(snapshot)
})
This code should work. Check for names if I made any mistakes and insert your data.
self.ref.child("Students").child("name").queryOrderedByChild("first name").queryEqualToValue("my name").observeSingleEventOfType(.Value) { (snapshot: FIRDataSnapshot) in
print(snapshot.value)
}
Before use queries with child, you need to specify this using ".indexOn":["name"] in Database Rules. See documentation for examples
{
"rules":{
".write": "true",
".read": "true",
"Students": {
"$key": {
".indexOn":["name"]
}
}
}
}
Your read/write rules can go where you need it. .indexOn is just like another rule, alongside with .validate

Updating Mongo Object Field

I'm trying to update an object stored in Mongo that gets created as part of every new users document when they register for my site. By default this object is empty.
How can I push data directly into this object which is within the subfield profile.history.
So far I have been only able to push data into the root of the document itself.
Looking at the image, as stated, I want to write to the history object in profile.
I think you're talking about the Meteor.users collection, below is some code:
let myDynamicField = 'foo'; // Or whatever you want, an input value for example...
let update = {};
update[`profile.history.${myDynamicField1}`] = 'blah';
Meteor.users.update(
{
"_id": "testing123"
},
{
$set: {
update
}
});
*Edited to reflect what the user was asking for in the comments.

Update nested array object (put request)

I have an array inside a document of a collection called pown.
{
_id: 123..,
name: pupies,
pups:[ {name: pup1, location: somewhere}, {name: pup2, ...}]
}
Now a user using my rest-service sends the entire first entry as put request:
{name: pup1, location: inTown}
After that I want to update this element in my database.
Therefore I tried this:
var updatedPup = req.body;
var searchQuery = {
_id : 123...,
pups : { name : req.body.name }
}
var updateQuery = {
$set: {'pups': updatedPup }
}
db.pown.update(searchQuery, updateQuery, function(err, data){ ... }
Unfortunately it is not updating anythig.
Does anyone know how to update an entire array-element?
As Neil pointed, you need to be acquainted with the dot notation(used to select the fields) and the positional operator $ (used to select a particular element in an array i.e the element matched in the original search query). If you want to replace the whole element in the array
var updateQuery= {
"$set":{"pups.$": updatedPup}
}
If you only need to change the location,
var updateQuery= {
"$set":{"pups.$.location": updatedPup.location}
}
The problem here is that the selection in your query actually wants to update an embedded array element in your document. The first thing is that you want to use "dot notation" instead, and then you also want the positional $ modifier to select the correct element:
db.pown.update(
{ "pups.name": req.body.name },
{ "$set": { "pups.$.locatation": req.body.location }
)
That would be the nice way to do things. Mostly because you really only want to modify the "location" property of the sub-document. So that is how you express that.

How to make the time stamp difference for inserting and updating record in mongo?

I need to create a time stamp in my mongodb collection. Am using C# in front end .My code is :
internal static void CreateStudent(string Id, string Name,string strUserId)
{
MongoServer server = MongoServer.Create(ConnectionString);
MongoDatabase mydb = server.GetDatabase("Database");
MongoCollection<BsonDocument> Student = mydb.GetCollection<BsonDocument>("Student");
BsonDocument colectionGenre = new BsonDocument {
{ "Code", Id }, //Id is Auto Generated in sql. Fetch from there using Output parameter and save it in one variable and pass that here
{ "Name", Name },
{ "Status","Y"},
{"stamps" , new BsonDocument {
{"Ins_date", DateTime.Now},
{"up_date",""},
{"createUsr", strUserId},
{"updUsr", ""},
{"Ins_Ip", GetIP()},
{"Upd_IP",""}}}
};
Student.Insert(colectionGenre);
}
internal static void UpdateStudent(string Id, string Name,string strUserId)
{
MongoServer server = MongoServer.Create(ConnectionString);
MongoDatabase mydb = server.GetDatabase("Database");
MongoCollection<BsonDocument>Student = mydb.GetCollection<BsonDocument>("Student"); ;
// Query for fetch the ID which is edited by the User...(user can only able to edit the NAME field alone)
var query = new QueryDocument {
{ "Code", Id }};
// After Fetch the correspondent ID it updates the name with the Edited one
var update = new UpdateDocument {
{ "$set", new BsonDocument("Name", Name) }
};
// Updated Query.(Id is same as previous. Name is updated with new one)
{"stamps" , new BsonDocument {
{"up_date",DateTime.Now},
{"updUsr", strUserId},
{"Upd_IP",GetIp()}}}
}}
};
Student.Update(query,update,UpdateFlags.Upsert, SafeMode.True);
}
It works fine for INSERT method with time(Stamp) once the record is created. But the problem is with update method. When user update something the insert time also changed with the updated time..
After User Updates the Name, i want my will collection looks like this
{
"_id" : ObjectId("5178aea4e6d8e401e8e51dc0"),
"Code": 12,
"Name": Sname,
"Stamps:"{
"Ins_date":03:34:00,
"up_date": 04:35:12
}
}
But my problem is both the time will same after update. That is because it takes the current date and time function..How can i achieve the above output.It needs any driver.Suggest something for me...
You're passing in a value for the Ins_date field when you're updating the document. Just remove that from the update document and it won't change it.
var update = new UpdateDocument {
{"$set", new BsonDocument {
{"State_strName", name},
{"stamps" , new BsonDocument {
{"up_date",DateTime.Now},
{"createUsr", ""},
{"updUsr", ""},
{"Ins_Ip", GetIP()},
{"Upd_IP",GetIP()}}}
};
tblmytbl.Update(query, update);
How you are updating the value in the existing document by using unique id or other unique value.Check whether the unique id or value is already exist in your database documents.If it is exist means change the update time only don't do anything..
While updating the data in mongoDB,you are passing the same values for Ins_date and up_date i.e. DateTime.Now(current system date and time).So the same values are updating in your monoDB document.
For this you can do one thing :-
Before updating your mongoDB document you take Ins_date values from your database by using sql query in C#.net and then use this value for Ins_date and for up_date use DateTime.Now then your both values will be different.
var update = new UpdateDocument {
{"$set", new BsonDocument {
{"State_strName", name},
{"stamps" , new BsonDocument {
{"Ins_date", **Ins_date values_from your database**} ,
{"up_date",DateTime.Now},
{"createUsr", ""},
{"updUsr", ""},
{"Ins_Ip", GetIP()},
{"Upd_IP",GetIP()}}}
};
tblmytbl.Update(query, update);
Sounds like what you need is the new $setOnInsert operator which was added in 2.4 for exactly this use case.
When the update with upsert flag results in an insert, you want to $set insert_date to Date.now but when it's a regular update, you don't want to set it at all. So now with your update you should use $set for regular fields you want to set whether it's an update or an insert, but use $setOnInsert for fields that should only be set during insert.
Finally I got answer...In INSERT method Simply pass the below things
{"Insert-stamps" , new BsonDocument {
{"Ins_date", DateTime.Now},
{"createUsr", strUserId},
{"Ins_Ip", GetIP()}}},
{"Update-stamps" , new BsonDocument {
{"up_date",""},
{"updUsr", ""},
{"Upd_IP",""}}}
And In UPDATE method
{"Update-stamps" , new BsonDocument {
{"up_date", DateTime.Now},
{"updUsr", StrUserId},
{"Upd_IP",GetIP()}}}
It works Fine for my standard....