Get multiple documents from collection using nodejs and mongodb - node.js

Hi I have two mongodb collections. The first one returns json data (array) and with the output of this, I want to return documents that match.
When I run Console.log (req.bidder.myBids) I get the following output:
[{"productId":"3798b537-9c7b-4395-9e41-fd0ba39aa984","price":3010},{"productId":"3798b537-9c7b-4395-9e41-fd0ba39aa984","price":3020},{"productId":"4c4bd71c-6664-4d56-b5d3-6428fe1bed19","price":1040},{"productId":"4c4bd71c-6664-4d56-b5d3-6428fe1bed19","price":1050},{"productId":"4c4bd71c-6664-4d56-b5d3-6428fe1bed19","price":1060},{"productId":"4c4bd71c-6664-4d56-b5d3-6428fe1bed19","price":1070},{"productId":"4c4bd71c-6664-4d56-b5d3-6428fe1bed19","price":1090},{"productId":"4c4bd71c-6664-4d56-b5d3-6428fe1bed19","price":1100}]
The productId has duplicates, I want to remove duplicates and then call a routine that finds all the products that match and output as json.
So far I have this code that only outputs one document, but cant figure out how to add the array of productId's and then fetch all corresponding products.
var agencyId = req.body.agencyId;
var productId = req.body.productId;
if (!validate.STRING(agencyId)) {
res.apiError(messages.server.invalid_request);
} else {
dbProduct.find({productId:{$in:['3798b537-9c7b-4395-9e41-fd0ba39aa984','4c4bd71c-6664-4d56-b5d3-6428fe1bed19']}
}).then(dbRes => {
console.log(dbRes);
Updated code and works with hard-wired productId and updated above code. Looking at how to get the array data and transpose replacing the hard-wired productId's

The $in operator is what you want. See the docs here: https://docs.mongodb.com/manual/reference/operator/query/in/

Related

How to get all the matching values from '$in' operator in mongoose

I have multiple checkboxes for different categories of blogs -
And what I want to achieve is that when I select some categories and click on filter, the specified selected blogs would be shown. I used query string parameters or URL parameters to send all the selected checkbox values to the nodejs backend -
query is an array containing all the selected categories
const response = await axios.get(`http://localhost:8000/blog/all?categories=${query}`)
And in the backend -
const cat = req.query.categories;
const all = await blogModel.find({ category: { $in: cat } });
I am passing the cat, which again consists of all the selected categories from the frontend, to $in to find all the matching blogs.
But the issue I am facing is that I am not getting matching blogs, say when I select the 'Science' checkbox and click on the filter I am able to get all the blogs having 'Science' as a category. But when I select say 'Science' & 'Food', I am getting an empty array as output even though I do have blogs of both categories in my MongoDB.
Backend console log of cat when I select 'Science' category -
And when I select 'Science' & 'Food' -
I get an empty array as output instead of all the blogs of 'Science' & 'Food' categories.
To summarize , when i select more than one categories i am getting an empty array instead of the blogs of the selected categories.And when i select only one category then i am able to get the selected blogs.It's not working for multiple categories
I am sure I am missing out on something but don't know what to google to get correct results. I also went through similar StackOverflow questions but I was not able to wrap my head around what needs to be done. I am building a simple blog website for my portfolio & thought of adding this 'filter by category' feature so that I would get to learn on how to filter values from MongoDB using mongoose. Please help me resolve this issue. Thank You.
Edit 1 - This is an example of a document from my collection
Also 'console.log(req.query.categories)' outputs this when i select 'Science' & 'Food' from the above checkbox -
I think you didnt path data as array to mongo query
first split by , and then pass to query
const cat = req.query.categories;
cat = cat.split(",")
const all = await blogModel.find({ category: { $in: cat } });
Yes there seems no issue in your query, make sure you are passing right data to backend like you saved "food" as category in database and searching for "Food" it will return empty array as it is case sensitive.
db.Posts.find({category: { $in:["Food","Gaming"]}})
You can also try this way to fetch
db.Posts.aggregate([{$match:{category: {$in:["cat","dog"]}}}])
const cat = req.query.categories;
var splitcat = cat .split(",");
db.Posts.find({category: { $in:splitcat }})

Get all documents whose property equals one of the elements in an array

I have a Post model that has a publisher property defined in its schema (I'm using Mongoose). The publisher property is a string that refers to a publisher's name.
I also have an array called sourceNames that holds all the different publisher names. I want to query my database for ALL the posts whose publisher matches any one of the array elements in sourceName. My current query looks like this:
const query = postModel
.find({ publisher: { $all: sourceNames } })
.limit(limit)
.skip(startIndex);
My query isn't returning anything when I exec it. Does anyone know if what I'm trying to do is possible in a single query (Rather than loop over sourceNames and make a query for each individual element?
Short
Just replace $all with $in
Expl
$all is trying to match an array with all elements in your array.
$in instead, tries to match a string or array with one in the array.

Differentiating missing documents in MongoDB find()

When I run the following query I am getting the document that matches as normal which is "LON" in this case.
But is there any way that I can make the response seperately return the values that didn't match or found, which is "BUJ" in this case. Instead of running a for loop for individual values.
ports = [
"LON",
"BUJ"
];
findDatas = async(coll, values, key) => {
let datas = await coll.find({[key] : values});
// let datas = await coll.find().where(key).in(values);
console.log(datas)
}
findDatas(airportsModel, ports, "iata_code")
In my DB I only have "LON" which mean "BUJ" is not found. So is there any way to make mongo to tell that the given values haven't been found? along with the found ones.
This code dynamically creates a $match stage to find the documents, the uses $facet to split into 2 pipelines, the first returns the documents, the second uses a $group stage created from the input array to count how many documents match each element. The result should be a document with 2 fields: documents and counts
matchdata={};
matchdata[key]={"$in":ports};
groupdata = {_id:null};
ports.forEach(function(p){
groupdata[p] = {"$sum":{"$cond":[{"$eq":["$" + key, p ]},1,0]}}
});
db.coll.aggregate([
{$match:matchdata},
{$facet:{
documents:[{$match:{}}],
counts:[{$group: groupdata},{$project:{_id:0}}]
}}
])

How to get object x or y in nested document

I know this has been asked before but I can't seem to find the answer, I want to get data/object in the nested array.
show image problem
schedule = await Schedule.findById({_id:'5b496ec3444152122c8d839e'})
console.log(schedule.datalayout.section.data.x)
If you want to get the specified field in the image, you need to determine field index in the array as down below:
console.log(schedule.datalayout.section[0].data[0].x)
And also, If you want to get all of the x fields in the data array, you need to write something like this:
for(let singleData of schedule.datalayout.section[0].data){
console.log(singleData.x)
}
// for using 'of' keyword, your function must be a async function.

Find all collections in mongodb with specific field

There is more than 40 collections in database I am currently working on.
One of the major key in all the collections is "account".
I need to know all such collections where there is a field called "account".
Is there a query to get or a js script which prints all such collections?
In Oracle I was using :
SELECT * FROM ALL_TAB_COLUMNS WHERE COLUMN_NAME LIKE 'account';
Any inputs is helpful.
Thanks in advance.
The following mongo script will print out all collection names where at least one document contains an account field.
db.getCollectionNames().forEach(function(collname) {
var count = db[collname].find({"account": {$exists: true}}).count();
if (count > 0) {
print(collname);
}
})

Resources