MongoDB $and query only works on Strings - node.js

I want to filter out data based on search criteria in mongoDb.
Here is the query:
exports.getParkingListByCriteria = async (req, res) => {
const cityQuery = req.body.city;
const stateQuery = req.body.state;
const countryQuery = req.body.country;
const zipQuery = req.body.zipCode;
try {
const filter = await Parking.find({
$and: [
{
"location.city": { $regex: new RegExp(cityQuery, ($options = "i")) },
"location.state": { $regex: new RegExp(stateQuery, ($options = "i"))},
"location.country": { $regex: new RegExp(countryQuery, ($options = "i"))},
"location.zipCode": zipQuery,
},
],
});
res.status(200).send(filter);
} catch (error) {
return res.status(500).json({ error: error.message });
}
};
City, state and country are stored as a String and zipCode is stored as a Number in mongoose model.
city, state and country filter was just working fine. It was giving me an intended results but then I added a zipCode query and now city, state and countries filter is also giving an empty array.
request I am sending from postman:
{
"city": "edmund",
"state": "lousinia",
"country":"australia",
"zipCode": 49755
}
All are stored in a one collection like shown below:
{"_id": {"$oid": "62cc46e920782c4be0673d50"},
"merchantId": {"$oid": 62c950ebc96c2b690028be8b"},
"contactInfo": {"name": "Ronda Green", "phoneNumber": 9104933588},
"about": "Laborum non minim ad",
"location":
{"address": "349 scott avenue",
"city": "edmund",
"state": "louisiana",
"zipCode": 49755,
"country": "australia"},
"price": 18,
"parkingType": "parkingLot",
"parkingInfo": [{"parkingName": "College Place","_id":"$oid":"62cc46e920782c4be0673d51"},"default": []}],
"totalSpots": [168],
"parkingSpotType": ["Motorbike","Large"],
"coordinates":
{"lng": 1.522645,
"lat": 125.939061},
"status": "active",
"isFeePaid": false,
"availability": [],
"specialEvents": [],
"__v": 0}
Before the introduction of zipQuery to the code every individual request was working perfectly fine (Like if I pass a query { "city": "edmund" } it would give me above result) but after the zipQuery it just got messy.
The result of console.log(zipQuery) is 49755

Related

Dynamodb scan on array of objects Filter Expression

I want to scan dynamodb using filter on product_id showing in below json of table.
Can anybody explain how to do scanning using filter of product_id.
Wants to scan dynamodb table data using documentclient.
Wants to find all fields which has product_id: something
{
"mandi_id": 1,
"product": [
{
"updated_price": 24,
"product_id": 2,
"last_price": 23
},
{
"updated_price": 24,
"product_id": 5,
"last_price": 23
}
],
"status": "active",
"createdAt": "2022-04-21T08:23:41.774Z",
"mandiCloseTime": "4pm",
"mandi_description": "anaj mandi",
"mandi_name": "gaziabad anaj mandi",
"state": "uttar pradesh",
"city": "gaziabad",
"main_image_s3": "",
"mandi_latlong": {
"lng": 77.48325609999999,
"lat": 28.680346
},
"mandiOpenTime": "10am",
"updatedAt": "2022-04-21T08:23:41.774Z",
"address_name": "gavindpuram",
"landmark_name": "mandi",
"village": "gaziabad",
"postal": "201013"
}
I have tried the following set of code but it is returning empty array list
var params = {
TableName: "dev-agrowave-mandi-management",
// Select: "ALL_ATTRIBUTES"
FilterExpression: "contains(#product,:product)",
ExpressionAttributeNames: {
"#product": "product",
},
ExpressionAttributeValues: { ":product": {"product_id":parseInt(id)}
}
};
let lastEvaluatedKey = 'dummy'; // string must not be empty
const itemsAll = [];
while (lastEvaluatedKey) {
const data = await docClient.scan(params).promise();
itemsAll.push(...data.Items);
lastEvaluatedKey = data.LastEvaluatedKey;
if (lastEvaluatedKey) {
params['ExclusiveStartKey'] = lastEvaluatedKey;
}
}
return {msg:itemsAll,params:params};

How to filter mongoDB in NodeJS API, checking if values are included in objects in array

I am writing REST API in NodeJS with MongoDB. Structure of the database is:
[
{
"_id": "12345",
"name": "Meal name",
"category": "dessert",
"area": "british",
"imageUrl": "https.image.jpg",
"instructions": "some instructions...",
"ingredients": [
{
"name": "salt",
"measure": "1g"
},
{
"name": "chicken",
"measure": "1"
},
{
"name": "butter",
"measure": "90g"
}, ...
]
}, ...
]
I can write a route to get data which meet one condition,
i.e.:
//getting all, when category = :category
router.get('/meals/category=:category', async (req, res) => {
try {
const meals = await Meal.find({category: req.params.category})
res.json(meals)
} catch (err) {
res.status(500).json({ message: err.message })
}
})
Here, route
'meals/category=vegetarian'
get all data with category = vegetarian.
However, I want to have route, which will filter all data by parameters: category, area, ingredients.
For example:
meals/ingredients=salt,pepper&category=dessert&area=american
should return all data, which contains salt and pepper in array, and category = dessert.
another example:
meals/area=american&category=dessert
should return all data, where area=american and category=dessert
How can I write the router.get() method to achieve that?

How to build a search endpoint in a API to find and filter results from a database

In my Node API and MongoDB, I'm trying to build an endpoint to search for data in the DB and get back the results to the client. My search goal is to show results from the Profile collection and in that way, I can build my queries to search by first name, surname, company and the combination of it as an example:
GET search?fn=joe or ?ln=doe or ?cp=Company or ?fn=...&ln=...&cp=...
Practically I can search in different ways and I can get for example all the people working for a company as a result of a search.
I would like to understand how can I achieve that with Mongoose/MongoDB and add also to the query optional a limit/pagination for the coming results.
I tried to make some simple trials but I got stuck as I do not really get it how to proceed next.
const SearchController = {
async getQuery(req, res) {
try {
const { fn, ln, cp } = req.query;
const searchResult = await Profile.find({
$or: [
{ firstname: fn },
{ surname: ln },
{
experience: {
company: cp
}
}
]
});
res.status(200).json(searchResult);
} catch (err) {
res.status(500).json({ message: err.message });
}
}
};
The JSON of a profile:
{
"imageUrl": "https://i.pravatar.cc/300",
"posts": [
"5e3cacb751f4675e099cd043",
"5e3cacbf51f4675e099cd045",
"5e3cacc551f4675e099cd046"
],
"_id": "5e2c98fc3d785252ce5b5693",
"firstname": "Jakos",
"surname": "Lemi",
"email": "lemi#email.com",
"bio": "My bio bio",
"title": "Senior IT developer",
"area": "Copenhagen",
"username": "Jakos",
"experience": [
{
"image": "https://via.placeholder.com/150",
"createdAt": "2020-02-04T13:47:37.167Z",
"updatedAt": "2020-02-04T13:47:37.167Z",
"_id": "5e3975f95fbeec9095ff3d2f",
"role": "Developer",
"company": "Google",
"startDate": "2018-11-09T23:00:00.000Z",
"endDate": "2019-01-05T23:00:00.000Z",
"area": "Copenhagen"
},
{
"image": "https://via.placeholder.com/150",
"createdAt": "2020-02-04T13:59:27.412Z",
"updatedAt": "2020-02-04T13:59:27.412Z",
"_id": "5e3978bf5e399698e20c56d4",
"role": "Developer",
"company": "IBM",
"startDate": "2018-11-09T23:00:00.000Z",
"endDate": "2019-01-05T23:00:00.000Z",
"area": "Copenhagen"
},
{
"image": "https://via.placeholder.com/150",
"createdAt": "2020-02-07T16:35:43.754Z",
"updatedAt": "2020-02-07T16:35:43.754Z",
"_id": "5e3d91dfb3a7610ec6ad8ee3",
"role": "Developer",
"company": "IBM",
"startDate": "2018-11-10T00:00:00.000Z",
"endDate": "2019-01-06T00:00:00.000Z",
"area": "Copenhagen"
}
],
"createdAt": "2020-01-25T19:37:32.727Z",
"updatedAt": "2020-02-04T23:14:37.122Z",
"__v": 0
}
The expected results are for example if I search the first name Joe I should get back all the profiles having as first name Joe. Similar for surname and company.
Please provide comments to allow me to understand if you need more scripts from the original code to see.
EDITED added the code modified of the search
// Models
const { Profile } = require("../models");
// Error handling
const { ErrorHandlers } = require("../utilities");
const SearchController = {
async getQuery(req, res) {
try {
const { fn, ln, cp } = req.query;
const query = {
$or: []
};
if (fn) query.$or.push({ firstname: fn });
if (ln) query.$or.push({ surname: ln });
if (cp) query.$or.push({ "experience.company": cp });
const searchResult = Profile.find(query, docs => {
return docs
});
if ((await searchResult).length === 0)
throw new ErrorHandlers.ErrorHandler(
404,
"Query do not provided any result"
);
res.status(200).json(searchResult);
} catch (err) {
res.status(500).json({ message: err.message });
}
}
};
module.exports = SearchController;
Have tried conditional query and modified your array search query for finding the company,
function findUser(fn, ln, cp) {
const query = {
$or: []
}
if (fn) query.$or.push({ firstname: fn })
if (ln) query.$or.push({ surname: ln })
if (cp) query.$or.push({ "experience.company": cp })
Profile.find(query, function (err, docs) {
if (err) {
console.error(err);
} else {
console.log(docs);
}
});
}
findUser("","","IBM")

Find data of those where referenced object id equals to user._id

I am getting all the order details
For example:(example of one order)
{
"customer": {
"id": "5db6ac89d85a2c1c709a42da",
"name": "Testing"
},
"product": {
"id": "5dba78427af9e73b18bdbb22",
"name": "image",
"seller": "Testing",
"price": 100,
"imgurl": "ok"
},
"_id": "5dba788fdeb78931f8a30105",
"quantity": 3
}
When I use find() I get all the elements but I only want to show the data of the one who is logged in
i.e where customer.id equals to req.user._id
I am using find() as shown in the code below:
router.get('/cart',verifyToken, async (req, res)=>{
const order = await Order.find({/* what should be the query here to get the desired result*/},'product , quantity , customer ');
try{
res.send(order)
}catch(err){
res.status(400).send(err);
}});
Any other methods to achieve this
You have to use findOne().Like below
const order = await Order.findOne({'customer.id':req.user._id}) // probably req.body.user._id
or
await Order.findOne( { customer: { id:req.user._id } } )
See the docs here

find object inside JSON using nested ID

i have a mongo collection like this
{"stores": [{"name": "foo",
"songs": [ {"id": "", "name": "", "artist": "", "category": "", "tags": []} ],
"songsSchedule": [
{
"song_id": "",
"date": ,
"user": "",
"help": ,
"partners": [{"user": ""}],
"likes":
}
]
}]}
and i want to get the songs name and artist from the songsSchedule song_id, i've tried this but it's not working
var query = { _id: fn.generateID(req.params.store_id), songsSchedule: { $exists: true } };
var select = { songsSchedule:1 };
var array = [];
client("stores", function(err, collection) {
if (err)
return res.json(fn.status("30"));
collection.findOne(query, select, function(err, store) {
if (err || !store)
return res.json(fn.status("31"));
for (var i in store.songsSchedule) {
var song = store.songsSchedule[i];
array.push(song.song_id);
}
collection.find({ _id: fn.generateID(req.params.store_id), "songs._id": { $in: array } }, function(err, songs) {
res.json(songs);
});
});
});
and i dont really know if it's the best way of doing it
I'm not entirely clear what you mean by "get the songs name and artist from the songsSchedule song_id" but it looks like that query will be messy.
If it were me, I'd consider splitting out songs and songSchedule into their own collections for easier querying.
from your document example, the "songs" field contains documents that do not contain an "_id" field.
"songs": [ {"name": "", "artist": "", "category": "", "tags": []} ]
But, your find() query is querying on the "songs._id" field.
Also, I'm not too familiar with the json() method, but does it handle cursors?
Regards,
Kay

Resources