Get the field of a mongodb document from URL Node.js - node.js

I am trying to create an API route where I pass the field in a mongodb database from the URL and it seems to be that the field is not processed properly as I get no result even though the db has entries that match the query.
the url has the following format: localhost:5000/api/animal/find/stripes/yes
in a general form: localhost:5000/api/animal/find/<FIELD>/<VALUE>
The value is handled properly but the field not.
My code to execute the query is as follows:
exports.getAttributeController = (req, res) => {
const field = req.params.field;
console.log(field); //DEBUG
const value = req.params.value
console.log(value); //DEBUG
Animal.find({
field: value
}).exec((err, animal) => {
if (err || !animal) {
return res.status(400).json({
error: 'No Animals found'
});
}
res.json(animal);
});
};
If I use console.log, I see that the correct values have been sent from the URL, and if I hardcode the field like this
Animal.find({
'stripes': value
...
I get a result, only when I try to insert the field variable, I get no result. How can I fix this?
Thanks in advance

You want to evaluate the value of field, so instead you want
Animal.find({
[field]: value // note the brackets that mean use the value of `field`
}).exec((err, animal) => {

Related

Update element of any particular index in an array in MongoDb using mongoose in Node.js

Hi I tried to update the element at a particular index in an array but I'm not able to update it. It is updating the entire array. Not able to figure out how to update any particular index. Also tried
{$set:{"Data.1:req.body}}
this is updating at 1st index but I don't want to hardcode the index value. It should take from frontend. Let say I have a schema in which I have Data who's type is array and default value is as shown below or anything in the same format.
Data: {
type: Array,
Default: ["0","1","0"]
}
Whenever I'll create a user then Data field will contain these default values, But now I want to update the value at any index (coming from frontend) of Data array of any user created.
I tried findByIdAndUpdate method but I don't know what to pass in set property. If I'm passing this {$set: req.body} and In postman I'm giving any value of Data then obviously it is updating Data array but I want to update value at any index which I'm passing from frontend, let say the index I'm passing is 2 then it should update the value of array at index 2, similarly I can pass any index from frontend how should I do that. What changes I have to make in {$set : } Thanks in advance.
Waiting for any help or suggestions. Thanks
It appears that you can solve this in backend logic if you are passing the index from the frontend.
You can dynamically specify the index, based on the input from the frontend, before you send a query.
const updateUserData = async (req, res) => {
const { index, user_id, new_value } = req.body;
try {
const update = {};
update[`Data.${index}`] = new_value;
const data = await Users.updateOne(
{ _id: user_id },
{ $set: update }
);
return res.status(200).json({ success: true });
} catch (error) {
return res.status(500).json({ success: false });
}
};

Node.js & MongoDB not reading variable correctly

Recently, I changed key of object in MongoDB.
{
links: {
changed: 'value',
notchanged: 'value'
}
}
This is what I get from my MongoDB collection. Data which key is not changed is still readable by links.notchanged but data which key is changed like links.changed is not readable and only outputs undefined. Node.js gets and reads the whole links data correctly but when it comes to links.changed it doesn't. How do I solve this problem? Code below:
scheme.findOne({}, (err, data) => {
if (err) res.send('ERR')
else {
console.log(data) // prints full data, same as JSON above
console.log(data.links.changed) // undefined
}
}
You are matching {class:'210'}.. Is it available in document. Probably Your query returns empty object in data . Confirm the match query... Otherwise your code seems ok.
await db1.findOne({class: "210"}, (err, data) => {
console.log(data.links.changed) // returns value
})
Or Try the code like this
await db1.find({ class: "210" }).toArray()
.then(data => {
console.log(data[0].links.changed) //"value"
});
You should make a variable instead of an object for this. For example: Use changed and assign it value as true or false

followers and following sytem

I am working on a social network web application I have established a system of following followers with firebase and node js , so I created a collection users and in it two following followers array, I managed to add them
Now I want to issue a condition to check if the user has already made a follow up not to add it a second time to the table how can i access to the tables (following, followers)in order to verify if the user is in
exports.onFollow = (req, res) => {
const followDocument = db.doc(`/users/${req.body.email}`);
const followerDocument = db.doc(`/users/${req.user.email}`);
let followData;
let followerData;
followDocument
.get()
.then((doc) => {
if (doc.exists) {
followData = doc.data();
if ('req.user.email', 'in', followData.followers.docs) {
return res.status(200).json({
error: 'user already follow'
});
} else {
followData.followers.push(req.user.email);
return followDocument.update({
followers: followData.followers
});
}
}
})
.catch((err) => {
console.error(err);
res.status(500).json({
error: err.code
});
});
It sounds like you want followers to be an array with unique values, so that each email address can only occurs once. Firestore has special arrayUnion operation for adding values to such a field.
From the documentation on updating elements in an array:
If your document contains an array field, you can use arrayUnion() and arrayRemove() to add and remove elements. arrayUnion() adds elements to an array but only elements not already present. arrayRemove() removes all instances of each given element.
var washingtonRef = db.collection("cities").doc("DC");
// Atomically add a new region to the "regions" array field.
washingtonRef.update({
regions: admin.firestore.FieldValue.arrayUnion("greater_virginia")
});
// Atomically remove a region from the "regions" array field.
washingtonRef.update({
regions: admin.firestore.FieldValue.arrayRemove("east_coast")
});
I'd recommend switching to using arrayUnion() for your use-case, as it prevents having to do the query to detect if the email address is already in the array.

Cloud firestore trigger query by documentID for array of ids

I am trying to write a transaction that first query documents by documentId from a list of ids, then makes some updates.
I am getting the error:
The corresponding value for FieldPath.documentId() must be a string or a DocumentReference.
For example:
const indexArray = [..list of doc ids...]
const personQueryRef = db.collection("person").where(admin.firestore.FieldPath.documentId(), "in", indexArray)
return db.runTransaction(transaction => {
return transaction.get(personQueryRef).then(personQuery => {
return personQuery.forEach(personRef => {
transaction.update(personRef, { ...update values here })
//more updates etc
})
})
})
I am wanting to do this in an onCreate and onUpdate trigger. Is there another approach I should be taking?
Update
The error still persists when not using a transaction, so this is unrelated to the problem.
The problem does not occur when the query is .where(admin.firestore.FieldPath.documentId(), "==", "just_one_doc_id"). So, the problem is with using FieldPath.documentId() and in.
It sounds like the type of query you're trying to do just isn't supported by the SDK. Whether or not that's intentional, I don't know. But if you want to transact with multiple documents, and you already know all of their IDs, you can use getAll(...) instead:
// build an array of DocumentReference objects
cost refs = indexArray.map(id => db.collection("person").doc(id))
return db.runTransaction(transaction => {
// pass the array to getAll()
return transaction.getAll(refs).then(docs => {
docs.forEach(doc => {
transaction.update(doc.ref, { ...update values here })
})
})
})

How can I pass parameters to a view using cradle (CouchDB)

Using cradle, how am I able to pass parameters to a view in CouchDB?
Update
Say I want to return documents which match other properties than _key (the default)...
// document format
{
_key,
postHeading,
postBody,
postDate
}
What if I wanted to match documents against the postHeading property... How would I go about this? What would the view look like, and how would I pass a search string to that view?
At the moment I'm doing this...
database.get("980f2ba66d5c8f9c91b9204a4d00022a", function (error, document)
{
});
I would like to access a view instead, and instead of the 40 character long auto-generated key, I'd like to pass a string, matching another property.
Something along the lines of this...
database.save("_design/posts", {
single: {
map: function (document)
{
if (document.postHeading == PARAMETER_PASSED_GOES_HERE)
emit(null, document);
}
}
});
database.view("posts/single", function (error, documents)
{
});
If you are querying a view try to pass second parameter as options object with your settings, for example:
db.view('characters/all', {descending: true}, function (err, res) {
res.forEach(function (row) {
sys.puts(row.name + " is on the " +
row.force + " side of the force.");
});
});
Also be aware of this:
Some query string parameters' values
have to be JSON-encoded.
EDIT:
As far as I know you can't create a view in CouchDB where you pass your custom parameter which will be used in map/reduce function code. You have to emit keys from your map function and based on them you can query the view with parameters like startkey and endkey. Try to look at Database Queries the CouchDB Way article.
db.get('vader', function (err, doc) {
doc.name; // 'Darth Vader'
assert.equal(doc.force, 'dark');
});
It looks like the searched value (parameter) here is 'dark' out of all force keys?
Cradle is also able to fetch multiple
documents if you have a list of ids,
just pass an array to get:
db.get(['luke', 'vader'], function
(err, doc) { ... });

Resources