I am using delete function in a scenario for cache deleting data from mongodb but how can i delete data which is specific object from redis. I used Lrem() but it didn't work, I would appreciate it if you could help me.
const deleteComment = async (req, res) => {
let key = `Comments/${req.query.postId}`;
try {
const deleteValue = await Comment.findOneAndDelete({
_id: req.params.id,
$or: [{ writer: req.user.id }, { authorId: req.user.id }],
})
.populate("responseTo", "writer")
.populate("postId", "authorId")
.populate("writer");
const jsonData = JSON.stringify(deleteValue);
await client.lRem(key, 0, jsonData);
res
.status(200)
.json({ success: true, message: "Comment Deleted", ıtem: deleteValue });
} catch (err) {
res.status(500).json({ message: err });
}
};
Do you have control over the code that inserts the JSON? If so, you'll need to make sure they generate the same strings. LREM requires an exact match to work. That said, you might want to consider a different data structure or maybe a combination of data structures.
One option is that you could store the JSON as a String and then the List could contain the keys to those Strings. Then, when you delete a comment, you call LREM to remove it from the List and UNLINK or DEL to remove the JSON. The List serves to store an ordered index of the comments. The comments themselves are each stored in a String.
If you can use RedisJSON, you could just store a JSON document with an array of the comments. That would give you ordered data and the data itself and then you could delete a particular comment using JSON.DEL and JSONPath.
Related
I tried to find the solutions over here but unable to get success while using $pull as the array values I have does not contain `mongo_id'.
So the scenario is that , I am trying to delete the specific comment of the particular user which I am passing through query params. M
My mongo data looks like this:
Now I am making API Delete request like this : http://localhost:8000/api/articles/learn-react/delete-comment?q=1 on my localhost .
ANd finally my code looks like this:
import express from "express";
import bodyParser from "body-parser";
import { MongoClient } from "MongoDB";
const withDB = async (operations, res) => {
try {
const client = await MongoClient.connect(
"mongodb://localhost:27017",
{ useNewUrlParser: true },
{ useUnifiedTopology: true }
);
const db = client.db("my-blog");
await operations(db);
client.close();
} catch (error) {
res.status(500).json({ message: "Error connecting to db", error });
}
};
app.delete("/api/articles/:name/delete-comment", (req, res) => {
const articleName = req.params.name;
const commentIndex = req.query.q;
withDB(async(db) => {
try{
const articleInfo = await db.collection('articles').findOne({name:articleName});
let articleAllComment = articleInfo.comments;
console.log("before =",articleAllComment)
const commentToBeDeleted = articleInfo.comments[commentIndex];
//console.log(commentToBeDeleted)
// articleAllComment.update({
// $pull: { 'comments':{username: commentToBeDeleted.username }}
// });
articleAllComment = articleAllComment.filter( (item) => item != commentToBeDeleted );
await articleAllComment.save();
console.log("after - ",articleAllComment);
//yaha per index chahiye per kaise milega pta nhi?
//articleInfo.comments = gives artcle comment
res.status(200).send(articleAllComment);
}
catch(err)
{
res.status(500).send("Error occurred")
}
},res);
});
I have used the filter function but it is not showing any error in terminal but also getting 500 status at postman.
Unable to figure out the error?
I believe you'll find a good answer here:
https://stackoverflow.com/a/4588909/9951599
Something to consider...
You can use MongoDB's built-in projection methods to simplify your code.
https://docs.mongodb.com/manual/reference/operator/projection/positional/#mongodb-projection-proj.-
By assigning a "unique ID" to each of your comments, you can find/modify the comment quickly using an update command instead of pulling out the comment by order in the array. This is more efficient, and much simpler. Plus, multiple read/writes at once won't interfere with this logic during busy times, ensuring that you're always deleting the right comment.
Solution #1: The recommended way, with atomic operators
Here is how you can let MongoDB pull it for you if you give each of your comments an ID.
await db.collection('articles').updateOne({ name:articleName },
{
$pull:{ "comments.id":commentID }
});
// Or
await db.collection('articles').updateOne({ name:articleName, "comments.id":commentID },
{
$unset:{ "comments.$":0 }
});
Solution #2 - Not recommended
Alternatively, you could remove it by index:
// I'm using "3" here staticly, put the index of your comment there instead.
db.collection('articles').updateOne({ name:articleName }, {
$unset : { "comments.3":0 }
})
I do not know why your filter is erroring, but I would recommend bypassing the filter altogether and try to utilize MongoDB's atomic system for you.
I am using the following code to get the details of a user when I pass their id as a parameter:
server.get("/users/:id", (req, res) => {
const itemId = req.params.id;
dbCollection.findOne({ _id: itemId }, (error, result) => {
if (error) throw error;
// return item
res.json(result);
});
});
However, this doesn't seem to work, as whenever I run the code, I get returned with a null value.
My question is not the same as many previously asked questions because I have ObjectId('randomId') as my id, and not a string. How can I fix my code?
req.params.id comes as a string while your _id is an ObjectId so this won't work since MongoDB requires type equality first, you need to cast the value:
const itemId = mongoose.Types.ObjectId(req.params.id);
MongoDB wouldn't consider the "itemId" as a MongoDB id, therefore you need to transform it as shown below:
new mongodb.ObjectId(itemId)
This implies that:
const mongodb = require('mongodb')
As others already said, MongoDB expects _id to be an ObjectID. But if you are searching for ONE item, instead of using findOne use findById, which accepts id as a string.
const { Model } = require('./models'); // Model is your Mongoose Schema
server.get("/users/:id", async (req, res) => {
const { id } = req.params;
// This is the same as Model.findOne({ _id: new ObjectId(id) });
const item = await Model.findById(id);
return res.json(item);
});
I would like to post multiple objects to my mongo database inside of an express route. Currently, everything is working fine when I do it as a single object (ie ONE casino), please see below, but instead of doing this a million times over, can someone help me do it as one giant data dump so I can post ALL my casinos?
Here is my route that works fine for posting a single object:
router.post('/post', async (req, res) => {
console.log(req.body);
const casinoD = new Casino({
casino: req.body.casino,
table_and_other: req.body.table_and_other,
poker: req.body.poker,
slot_machines: req.body.slot_machines,
total_gaming_win: req.body.total_gaming_win,
year: req.body.year,
month: req.body.month,
combined_date: req.body.combined_date
})
try {
const newCasino = await casinoD.save()
res.status(201).json(newCasino)
} catch (err) {
res.status(400).json({ message: err.message})
}
})
I also understand mongoimport is a better way to do this - however that had its own issues in of itself.
Thanks
Like #JDunken said, you can iterate over the POST body as an array and insert in bulk. You'll want to use
insertMany for speed. To insert millions of records, you will probably want to put a sane limit on the number of records per request, and send API requests in batches. Validation is optional, as Mongoose will run validation according to the schema. It depends on how you want to handle validation errors. Make sure to read up on the ordered and rawResult options for that as well.
router.post('/post', async (req, res) => {
// you should sanity check that req.body is an array first, depending on how robust you want error handling to be
const casinos = req.body.filter(input => isValid(input));
try {
const insertedCasinos = await CasinoModel.insertMany(casinos, { ordered: false });
res.status(201).json(insertedCasinos)
} catch (err) {
res.status(400).json({ message: err.message})
}
})
const isValid(input) {
let valid = true;
// implement input validation
return valid;
}
I have a simple json object like so.
{
"gymData": {
"previousWorkouts": [
],
"exercises": [
]
}
}
both of the arrays above, are full of objects. I have 2 end points /workouts and /exercises.
my backend is just a simple express server with custom end points. when I add a new workout in the frontend and click submit, the /workouts endpoint behaves correctly.
however, I'm getting some issue when it's not updating the json correctly and resulting in a json error.
this is my node endpoint code
app.post("/exercises", function(req, res) {
fs.readFile('db.json', 'utf8', function (err, data) {
if (err) throw err;
let databaseData = JSON.parse(data);
const workoutExercises = req.body.workoutExercises.workouts
workoutExercises.forEach(exercise => {
const filteredExerciseDatabase = databaseData.gymData.exercises.filter(ex => ex.name === exercise.name)
filteredExerciseDatabase[0].previousWeights.push({date: req.body.date, weight: exercise.weight})
})
const updatedData = JSON.stringify(databaseData)
console.log(updatedData)
fs.writeFile('db.json', updatedData, 'utf8', function(err, data) {
if (err) throw err;
res.status(200).send("Basket was updated");
});
});
})
instead of writing the whole file again. I was wondering if I can just update the specific object key that I need too?
also, for reference, the error seems to be appending extra stuff onto the json object, so it's breaking. but in this line: console.log(updatedData) when I copy that logged data into a json validator, it is valid. so I'm confused as to why it's not writing the correct thing :/
I'm trying to delete and object from my Elasticsearch result query, but this object persist whatever I do:
Here is my code :
exports.searchUserByKeyWord = (req, res) => {
User.search(byKeyWordQuery(req), geoDistance(), (err, users) => {
if (err) requestError(res, err)
let result = []
for(let user of users.hits.hits) {
delete user.address.full
result.push(user)
}
sendJsonResponse(res, 200, result)
})
}
Like you can see I'm using delete but it doesn't work, what I can't understand here is the fact that when I replace sendJsonResponse(res, 200, result) with
sendJsonResponse(res, 200, result[0].address.full) I found out that this address got successfully deleted, but when I test my API with Postman without adding result[0].address.full the address full field is still there ...
are you reindexing your elasticsearch data after you delete? the indexed record may persist even though you have removed the document from disk
more on this can be read #
https://www.elastic.co/guide/en/elasticsearch/guide/current/update-doc.html