I have several objects like this:
"status": "published",
"term_id": [
"anime",
"sci-fi",
"etc"
],
"captionCert": "1",
I know that in order to look within a single field, I would create something like this:
if (keyword) {
query.status = { $regex: keyword, $options: 'i' };
}
Where keyword comes from the front end and can be whatever the user types; then I proceed to look into the field status and then I just retrieve it by passing it into my model query:
Video.find(query)
Now hte problem is that I need to know how to exactly do this but inside the term_id array?
Any idea? Thanks.
UPDATE: I'm trying to implement it into this function:
exports.searchVideos = asyncHandler(async (req, res, next) => {
const query = {};
const { keyword } = req.query;
if (keyword) {
query.title = { $regex: keyword, $options: 'i' };
} else {
query.text = { $regex: keyword, $options: 'i' };
}
if (keyword) {
query.term_id = { term_id: { $regex: keyword, $options: 'i' } };
};
const video = await Video.find(query).select(
'title text thumbnail video_url term_id'
);
console.log(query);
res.status(200).json({ success: true, data: video });
});
Solution after finding out about $or operator. This solved my problems!:
exports.searchVideos = asyncHandler(async (req, res, next) => {
let query = {};
const { keyword } = req.query;
query = {
$or: [
{ title: { $regex: keyword, $options: 'i' } },
{ text: { $regex: keyword, $options: 'i' } },
{ term_id: { $regex: keyword, $options: 'i' }}
]
};
const video = await Video.find(query).select(
'title text thumbnail video_url term_id'
);
res.status(200).json({ success: true, data: video });
});
Related
I want to make full dynamic search, when user used to type one or two string characters of book in book store UI at search box it should bring all match value from my book table that can be entire my table.
The kind of object that user want to search is not important it should bring all matched values.
const searchObjects = req.query;
const result =await modelbook.find({
//this place is for query that i don't know how I should write
});
res.status(200).json({resultis: result});
})
and book model has these properties
name
price
Url
author
...
You should use $regex.
const search = asyncWrapper(async (req, res) => {
var { value } = req.query;
const result = await modelbook.find({
$or: [
{ name: { $regex: value, $options: "i" } },
{ price: { $eq: Number(value) ? +value : 0 } },
{ url: { $regex: value, $options: "i" } },
{ description: { $regex: value, $options: "i" } },
{ author: { $regex: value, $options: "i" } }
],
});
res.status(200).json({ resultis: result });
})
I have written a mongoose find query for the following schema
{
_id: "12345678",
date: 2021-08-16T04:26:18.000Z,
en: {
title: "some title",
subtitle: "some subtitle",
content: [
{
main: "some content",
},
],
}
}
I want to return _id, date and everything inside en key, so it would look like this:
{
_id: "12345678",
date: 2021-08-16T04:26:18.000Z,
title: "some title",
subtitle: "some sub title",
content: [
{
main: "some content",
},
],
}
I'm wondering if I can do that using select populate or any other method in mongoose. I'm using express js in my backend.
This is my current query:
exports.post_list = function (req, res, next) {
PostSchema.find(
{ visible: true },
{ visible: 0, es: 0 },
function (err, posts) {
if (err) return next(err);
res.send(posts);
}
);
};
There is a way to do this for sure
Try this
let searchValue="";
let requestCondition = [{Add your conditions here}];//_id:1
let regex = new RegExp(searchValue,'i');//i is a flag
requestCondition.push({$or: [
{ "_id": { $regex: regex } },
{ "_date": { $regex: regex } },
{ "_title": { $regex: regex } },
{ "subtitle": { $regex: regex } },
{ "contents": { $regex: regex } }
]});
}
requestCondition = {$and: requestCondition}
let result = await modelName.find(requestCondition)
.sort( { _id : -1 } )
.skip(pg.skip)
.limit(pg.pageSize)
.exec();
let total = await modelName.find(requestCondition).countDocuments();
return {
"pagination":CallYourPaginationObject(pg.pageNo,pg.pageSize,pg.skip,total,result.length),
"data":result
};
}
you can write a recursive function to do this. or you can simply write a projection in your mongodb query to return just the en and _id.
for additinal information about mongo project read this article.
https://docs.mongodb.com/manual/reference/operator/aggregation/project/
I found the solution for my problem. Thanks to Muhammad Mujtaba Shafique and Amir Almian for their comments
PostSchema.find(
{ visible: true },
{
_id: 1,
date: 1,
title: '$en.title',
subtitle: '$en.subtitle',
content: '$en.content',
},
function (err, posts) {
if (err) return next(err);
res.send(posts);
}
);
I am using the $or operator in mongoose for searching through the name and description fields of the database. I want to check if the queryWord string contains any part of the database field(s). This is the code I am using:
const query = {
$or: [
{ name: `/${body.queryWord}/i` },
{ description: { $regex: `/${body.queryWord}/i` } },
],
};
Food.find(query, (err, data) => {
if (err) {
res.status(500).send(err);
} else {
res.status(200).send(data);
}
});
But it returns, only, an empty array!
Any help is greatly appreciated!
Thank You!
I think the problem is because you wrap the regular expression in ``, which is understood as a string. You can try this way:
const queryWordRegex = new RegExp(body.queryWord, "i");
const query = {
$or: [
{ name: { $regex: queryWordRegex } },
{ description: { $regex: queryWordRegex } },
],
};
I got one record with admin.name = "FooBar"
And I want to do a findOne on the name but case insensitive.
In Studio3T this works fine...
db.admin.findOne(
{ name: { $regex: /^FoObAr/i } }
)
But in nodeJS I cant seem to get a variable containing the regexp into the find statement...
Let ID = "FoObAr"
return resolve( adminModel.findOne( { "name" : { $regex: "/^" + ID + "$/i"} } ) );
This one results in... (which gives 0 results)
Mongoose: admin.findOne({ name: { '$regex': '/^FoObAr$/i' } }, { projection: {} })
I also tried
Let ID = "FoObAr"
return resolve( adminModel.findOne( { "name" : { $regex: /^ ID $/i } ) );
This one results in... (which gives 0 results)
Mongoose: admin.findOne({ name: { { $regex: /^ ID $/i } }, { projection: {} })
Any ideas?
Please use RegExp function
admin.find({name:new RegExp(['^',ID, '$'].join(''), 'i')}).projection({})
You should pass RegExp object, not string.
adminModel.findOne({ "name" : { $regex: new RegExp(/^FoObAr/, 'i') } })
With variable ID it will look like
adminModel.findOne({ "name" : { $regex: new RegExp(`^${ID}$`, 'i') } })
I am passing blank('') value in search parameter, it display no record. I want, when i pass null or blank value it ignore that parameter from search query, and display record. My code is
var _branchName = req.query.branchName;
var _personName = req.query.personName;
var _clientID = req.query.clientID;
var _searchQRY = [
{
branchName: { $regex: _branchName, $options: '-i' }
},
{
personName: { $regex: _personName, $options: '-i' }
},
{
"client._id": _clientID
},
{
isDeleted: { $ne: true }
}];
objModel.find({ $and: _searchQRY }, function (err, results) {
res.json({ status: config.responseStatus, record: results })
});
In this i pass "_clientID" is blank(''). At that time i want to ignore that parameter and search on remains parameter.
You can do smth like
var _branchName = req.query.branchName;
var _personName = req.query.personName;
var _clientID = req.query.clientID;
var _searchQRY = [
{
branchName: { $regex: _branchName, $options: '-i' }
},
{
personName: { $regex: _personName, $options: '-i' }
},
{
isDeleted: { $ne: true }
}];
if (_clientID) {
_searchQRY.push(
{
"client._id": _clientID
}
);
}
objModel.find({ $and: _searchQRY }, function (err, results) {
res.json({ status: config.responseStatus, record: results })
});
I.e. include client._id in the search query only when you do specify it in the request.
What you can do is, when _clientID is blank, change its value to object like this
if (_clientID == '')
_clientID = { $exists : true};
This will match all the client._id when _clientID is empty string ''