Partialy repair a mongo database - mongodb

I have a mongodb with my users in it. Users are like that :
_id: ObjectId,
created_at: Date,
username: String
I don't know why but all my users created_at fields have been reset.
I have a save but i can't just use my save and replace all my users by the save because i always have new users. I just need to replace all existing users created_at field by their own created_at field in the save.
I can use mongoose and node.js to do that (i don't know how but i can find) But i would prefer to do that using only mongodb functions. My saves are on .bson format.

You could create a local database, put your .bson in it. Then do a request to your local db to get all users and save theme in a .json file. Then update your user with wrong date with your saved datas.
Puting your bson file in your database
mongorestore -d yourdatabase -c yourcollection "users.bson"
Set all your good users in a json file
db.model('User').find({}, { created_at: 1 }).exec(function(error, _users) {
jsonUsers = _users;
jsonUsers = JSON.stringify(jsonUsers);
fs.writeFile('myjsonfile.json', jsonUsers, 'utf8', (err) => {
});
});
Update your wrong users to be good again
const jsonUsers = require('../myjsonfile.json');
db.model('User').find({}, { created_at: 1 }).exec(function(error, _users) {
if (error) return ;
_users.forEach((wrongUser) => {
let goodUser = jsonUsers.find((gU) => { return gU._id == wrongUser._id });
if (goodUser) {
wrongUser.created_at = goodUser.created_at;
wrongUser.save(cb);
} else {
//this is on of your new user that where not in your .bson file
}
});
});

Related

How to insert bulk data one db to another db?

I am new to MongoDB. I want to copy some old data from one database to another new database.
I wrote a script that works, but I want to same change in my old data.
Present my data format is:
user {
_id: 1,
username: "jon",
email: "jon#gmail.com"
}
But I want this format:
user {
_id: "621721aed6d2481c999429e5",
username: "jon",
email: "jon#gmail.com",
old_id: 1
}
My script is:
var bulk = db.getSiblingDB("blog-new")["users"].initializeUnorderedBulkOp();
db.getCollection("users").find().forEach(function (d) {
bulk.insert(d);
});
bulk.execute();
How can I solve this issue?
Update
solve this issue using this script-
var bulk = db.getSiblingDB("user-new")["users"].initializeUnorderedBulkOp();
db.getCollection("users").find().forEach(function (d) {
d.old_id = NumberInt(d._id)
d._id = ObjectId()
print("user", d);
bulk.insert(d);
});
bulk.execute();

How to pass data for sync function using watermelondb

Good day everyone, I am working with watermelondb and I have the code below, but I don't know how to actually use it. I am new in watermelondb and I don't know how to pass data as props to the pullChanges and pushChanges objects. How do I pass necessary data like changes and lastPulledAt from the database into the sync function when I call it. And I need more explanation on the migrationsEnabledAtVersion: 1 too. Thanks in advance for your gracious answers.
import { synchronize } from '#nozbe/watermelondb/sync'
async function mySync() {
await synchronize({
database,
pullChanges: async ({ lastPulledAt, schemaVersion, migration }) => {
const urlParams = `last_pulled_at=${lastPulledAt}&schema_version=${schemaVersion}&migration=${encodeURIComponent(JSON.stringify(migration))}`
const response = await fetch(`https://my.backend/sync?${urlParams}`)
if (!response.ok) {
throw new Error(await response.text())
}
const { changes, timestamp } = await response.json()
return { changes, timestamp }
},
pushChanges: async ({ changes, lastPulledAt }) => {
const response = await fetch(`https://my.backend/sync?last_pulled_at=${lastPulledAt}`, {
method: 'POST',
body: JSON.stringify(changes)
})
if (!response.ok) {
throw new Error(await response.text())
}
},
migrationsEnabledAtVersion: 1,
})
}
Watermelondb's documentation is terrible and its link to typescript even worse.
I spent almost a week to get 100% synchronization with a simple table, now I'm having the same problems to solve the synchronization with associations.
Well, the object you need to return in pullChanges is of the following form:
return {
changes: {
//person is the name of the table in the models
person: {
created: [
{
// in created you need to send null in the id, if you don't send the id it doesn't work
id: null,
// other fields of your schema, not model
}
],
updated: [
{
// the fields of your schema, not model
}
],
deleted: [
// is a string[] consisting of the watermelondb id of the records that were deleted in the remote database
],
}
},
timestamp: new Date().getTime() / 1000
}
In my case, the remote database is not a watermelondb, it's a mySQL, and I don't have an endpoint in my API that returns everything in the watermelon format. For each table I do a search with deletedAt, updatedAt or createdAt > lastPulledAt and do the necessary filtering and preparations so that the data from the remote database is in the schema format of the local database.
In pushChanges I do the reverse data preparation process by calling the appropriate creation, update or deletion endpoints for each of the tables.
It's costly and annoying to do, but in the end it works fine, the biggest problem is watermelon's documentation which is terrible.

Discord.js/Mongodb How to update all database values

I am currently creating an economy bot for Discord, and i have a problem i don't know how to solve:
All users have a salary, that will be set with a command. I want to create a command that can update all users account with the set salary amount.
Instead of having to ping a specific user, how could i make it that the command would update values of all found users in the MongoDB Database?
Here is current code:
const profileModel = require("../models/profileSchema");
module.exports = {
name: 'pay',
aliases: [],
permissions: ["ADMINISTRATOR"],
description: "pay users their salary",
async execute(message, args, cmd, client, discord, profileData) {
const amount = profileData.pay;
const target = message.mentions.users.first();
try{
await profileModel.findOneAndUpdate({
userID: target.id,
}, {
$inc: {
bank: amount,
},
}
);
return message.channel.send(`Users have been paid.`);
} catch(err) {
console.log(err);
}
},
};
As you can see, currently its waiting for the user to ping a user. But i would want it to just update all found users inside the Database without needing to specify who it is.
I would really appereciate help!
Mongo has the method updateMany, docs found here, which updates all documents if the query is set to an empty object. So, just try:
await profileModel.updateMany({}, {
$inc: {
bank: amount,
},
}
);

FireStore: How to merge timestamp data to existing document?

I am new to FireStore and and building an app where users can bookmark photo documents and show them on their personal feed. This works fine. Now, I want to be able to sort the bookmarks by bookmarked date when the user is viewing their personal feed (orderBy method). Thus, to make this happen, I figured I'd add a timestamp value at the moment the user bookmarks the document.
Here's my attempt. I wanted to verify with the community whether this is a good way to do it. I am concerned about redundancy and extra writes.
async addDocToFeed({state}, doc) {
try {
const feedRef = this.$fireStore
.collection(`users/${state.userProfile.uid}/feed`)
.doc(doc.id)
await feedRef.set(doc) < --- copy record to user's feed collection (see json sample below)
const bookmark = this.$fireStore
.collection(`users/${state.userProfile.uid}/feed`)
.doc(doc.id)
bookmark.update({
bookmarked: this.$fireStoreObj.FieldValue.serverTimestamp()
})
// })
console.log('doc bookmarked')
} catch (error) {
console.error('error updating doc', error)
}
}
Example JSON of doc before adding the timestamp:
{"id":"1KecNCqYlcVRjq4BLCbZ","comments":"__vue_devtool_nan__","url":"https://firebasestorage.googleapis.com/v0/b/vue-photoapp-api.appspot.com/o/photos%2F0.jpg?alt=media&token=ee23b95b-b5d8-4abe-b1b9-e335d591b413","tags":["router","Texas"],"filename":"0.jpg","description":"test with new router setup","createdAt":{"seconds":1596020630,"nanoseconds":473000000},"title":"test with new router setup","status":"Unsolved","userId":"SvuTxDtHXJdBHImNQWByqnO3F2U2","displayName":"MrRouter"}
I tried to do:
await feedRef.set({doc, bookmarked: this.$fireStoreObj.FieldValue.serverTimestamp()}, {merge: true})
but that erased all the data and only added the bookmarked timestamp.
Thanks for any advice or assurances I'm on the right track (or not)
this
.$fireStore
.collection(users/${state.userProfile.uid}/feed)
.doc(doc.id);
.set({
bookmarked: Date.now()
}, {merge: true})
.then(() => {
resolve(true);
}).catch((error) => {
reject(error)
})
This should work.

Data Saves to MongoDB Database but not views in command

I use this code to store my data into MongoDB database but it does not view in the database .. and when I use find() to find, it shows my data but not shows when I use db.pick.find() in command. I may be missing something when I setup mongo so please help me.
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/pick', { useNewUrlParser: true })
mongoose.connection.once('connected', function(){
console.log("Open Connection")
})
var catSchema = new mongoose.Schema({
name: String,
age: Number
});
var Cat = mongoose.model("Cat", catSchema);
var newc = new Cat({
name: "cutie",
age: "4"
});
newc.save((err,c) =>{
if(err){
console.log("NewC Err")
}else{
console.log(c)
}
});
Okay atul,
Your database's name is Pick, but when you do this query:
db.pick.findOne({}), you're technically saying that the database must find a document from the pick collection. But looking at the code, cat is the name of your collection.
you can use the show collections; command to get the collection names in mongodb and then you can query like this:
Select the Database
use pick;
get the collection list
show collections;
query the collection
db.collectionName.findOne({})