MongoDB query using $and and $or - javascript

I trying to perform a query using $and and $or in MongoDB. Sadly I've had no luck. I found several similar questions posted here on Stack Overflow, this one came closest.
mongodb queries both with AND and OR
Unfortunately the solution did not work for me. I want to allow user to search by project id or title. I do have code that check if the q variable past in is a valid ObjectId before I include it.
Here is my query:
Project.find({
$and : [
{ $or : [ { title: {$regex : req.body.q} }, { _id: req.body.q } ] },
{ userID: req.session.userID }
]
}).then(project => {
console.log(project);
});
sample document:
{ "_id" : ObjectId("5afb583e8341f161a0c950af"), "title" : "Learn Node.js", "status" : "In Progress", "createdOn" : "2014-06-05 22:39:00.000Z" }
{ "_id" : ObjectId("4fe8736dc27bc8be56947d61"), "title" : "Learn MongoDB", "status" : "In Progress", "createdOn" : "2014-06-05 22:39:00.000Z" }
What am I missing?

Related

Search for keywords in array and only get the matching elements in MongoDB using NodeJS

I have a collection asset and This is my Data
{
"_id" : ObjectId("5e71d235a3b5401685a058"),
"company" : ObjectId("5e6b834b5991d70945840"),
"asset_name" : "LG-OLED-55-Inch",
"installedAt" : ["lobby", "storeroom", "f105"],
}
{
"_id" : ObjectId("5e71d235a3b540168475d8"),
"company" : ObjectId("5e6b834b5991d70945840"),
"asset_name" : "LG-OLED-32-Inch",
"installedAt" : ["lobby", "f108"],
}
{
"_id" : ObjectId("5eb3d53a7e16dc70244d6578"),
"company" : ObjectId("5e6b834b5991d70945840"),
"asset_name" : "LG-OLED-68-Inch",
"installedAt" : ["tvroom", "f105"],
}
{
"_id" : ObjectId("5eb3d53a7e16dc7024474a12"),
"company" : ObjectId("5e6b834b5991d70945840"),
"asset_name" : "LG-OLED-22-Inch",
"installedAt" : ["tvroom"],
}
So for the above data my requirement is to search for keyword in installedAt and return all the elements that match the keyword which user provides.
For Example, if the user searches for f10 then we should search all the installedAt arrays in assests and return like below
"installedAt": ["f105","f108"]
And I have tried using $in for getting similar elements but it is not working as I have expected.
This is my query
var autoRecords =[];
key = [searchString];
key.forEach(function(opt){
autoRecords.push(new RegExp(opt,"i"));
});
Assets.find({ "installedAt" : {"$in" : autoRecords},"company": companyId},{"installedAt" : 1})
So for the above query when I try to send search text which is f10 the result is as below
[
{"installedAt":["lobby", "storeroom", "f105"],"_id":"5e71d235a3b5401685a058"},
{"installedAt":["lobby", "f108"],"_id":"5e71d235a3b540168475d8"},
{"installedAt":["tvroom", "f105"],"_id":"5eb3d53a7e16dc70244d6578"},
]
It is getting all elements in the installedAt array even if it finds one. So Can anyone help me in getting only matched elements in the array and try to obtain this format
"installedAt": ["f105","f108"]
You can use below aggregation
const data = await Assets.aggregate([
{ $match: { installedAt: { $regex: "f10", $options: "i" }}},
{ $unwind: "$installedAt" },
{ $match: { installedAt: { $regex: "f10", $options: "i" }}},
{ $group: {
_id: null,
data: { $addToSet: "$installedAt" }
}}
])
MongoPlayground

Retrieve Just A Element From Mongodb

I'm trying to retrieve just a lesson from a classes collection based on it's id. I put together the following from previous answers, but it doesn't return anything. Can someone point me in the right direction?
My Code
Class.aggregate([
{$match: {'lessons._id': id}},
{$project: {
lessons: {$filter: {
input: '$lessons',
as: 'lesson',
cond: {$eq: ['$$lesson._id', id]}
}},
_id: 0
}}
])
Example
{
"_id" : ObjectId("14354"),
"title" : "Easy Math",
"instructor_id" : "2454",
"lessons" : [
{
"lesson_body" : "2 + 2 = 4",
"lesson_title" : "Addition",
"_id" : ObjectId("3456")
},
{
"lesson_body" : "4 - 2 = 2",
"lesson_title" : "Subtraction",
"_id" : ObjectId("4456")
}
],
"__v" : 0
}
{
"_id" : ObjectId("5345"),
"title" : "Harder Math",
"instructor_id" : "6345",
"lessons" : [
{
"lesson_body" : "2 * 2 = 4",
"lesson_title" : "Multiplication",
"_id" : ObjectId("7454")
}
],
"__v" : 0
}
Shouldn't it be lessons instead of lesson
on this line :
cond: {$eq: ['$$lessons._id', id]}
Hope this will help you:
db.COLLECTION_NAME.find({ lessons: { $elemMatch: { "_id" : ObjectId("3456")} } })
I am not totally sure, but remember having similar issues. Also I think your syntax looks somewhat strange? Try to adapt to this, this is how I have learned it should look atleast:
var objectId = require('mongodb').ObjectID;
And then when you try to get the object by ID:
db.collection("classes").findOne({"_id": new ObjectID(id)}
Feel free to find inspiration here: github repository

Mongo db update to array object

I have array object inside my collection. i'm getting extra square bracket when i try to update data into the array object.
here is the code.
var comments = [{
'COMMENTED_BY' : employee.SYSTEM_USER_ID,
'COMMENT' : employee.FIRST_NAME+" "+employee.LAST_NAME+" Started working on this comlaint"
}];
if(req.body.complaint.comment){
comments.push({'COMMENTED_BY' : employee.SYSTEM_USER_ID,'COMMENT': req.body.complaint.comment});
}
Complaint.findByIdAndUpdate(
req.body.complaint.complaintId,
{$set: {'STATUS': 1}, $push: {"COMMENTS": comments}},
{safe: true, upsert: true},
function(err, model) {
My collection looks like below
{
"COMMENT" : "media delete confirmation UI issue",
"COMMENTED_BY" : ObjectId("575cc0b39dd420a41d202dad"),
"_id" : ObjectId("575fe9e1a5ee92201b58011e"),
"CREATED_AT" : ISODate("2016-06-14T11:26:25.003Z")
},
{
"COMMENT" : "Could someone explain to me how Luke Ronchi gets in when Tom Latham is a very capable keeper as well as batsman? Why not another specialist batsman/bowler?",
"COMMENTED_BY" : ObjectId("575cc0b39dd420a41d202dad"),
"_id" : ObjectId("575fea19a5ee92201b58011f"),
"CREATED_AT" : ISODate("2016-06-14T11:27:21.136Z")
},
[
{
"COMMENT" : "media delete confirmation UI issue",
"COMMENTED_BY" : ObjectId("575cc0b39dd420a41d202dad"),
"_id" : ObjectId("575fe9e1a5ee92201b58011e"),
"CREATED_AT" : ISODate("2016-06-14T11:26:25.003Z")
},
{
"COMMENT" : "Could someone explain to me how Luke Ronchi gets in when Tom Latham is a very capable keeper as well as batsman? Why not another specialist batsman/bowler?",
"COMMENTED_BY" : ObjectId("575cc0b39dd420a41d202dad"),
"_id" : ObjectId("575fea19a5ee92201b58011f"),
"CREATED_AT" : ISODate("2016-06-14T11:27:21.136Z")
}
]
i want to remove the extra [] brackets
This is happening because, you are just pushing array of objects, comment, into COMMENTS array field while updating. Use $each instead, while pushing array of objects.
See doc-$each for more info.
Try the following query. :-
Complaint.findByIdAndUpdate(
req.body.complaint.complaintId,
{$set: {'STATUS': 1}, $push: {"COMMENTS":{$each : comments}},
{safe: true, upsert: true})
Hope this will solve your issue.

How to get element from collection in Meteor if it multi-dimensional array or object or both?

I have collection "groups". like this:
{
"_id" : "e9sc7ogDp8pwY2uSX",
"groupName" : "one",
"creator" : "KPi9JwvEohKJsFyL4",
"eventDate" : "",
"isEvent" : true,
"eventStatus" : "Event announced",
"user" : [
{
"id" : "xfaAjgcSpSeGdmBuv",
"username" : "1#gmail.com",
"email" : "1#gmail.com",
"order" : [ ],
"price" : [ ],
"confirm" : false,
"complete" : false,
"emailText" : ""
},
...
],
...
"buyingStatus" : false,
"emailTextConfirmOrder" : " With love, your Pizzaday!! "
}
How can I get a value of specific element? For example i need to get value of "Groups.user.confirm" of specific group and specific user.
I tried to do so in methods.js
'pizzaDay.user.confirm': function(thisGroupeId, thisUser){
return Groups.find({ _id: thisGroupeId },{"user": ""},{"id": thisUser}).confirm
},
but it returns nothing.
Even in mongo console I can get just users array using
db.groups.findOne({ _id: "e9sc7ogDp8pwY2uSX"},{"user": ""})
The whole code is github
http://github.com/sysstas/pizzaday2
Try the following query:-
db.groups.aggregate(
[
{
$match:
{
_id: thisGroupeId,
"user.id": thisUser
}
},
{
$project:
{
groupName : 1,
//Add other fields of `user` level, if want to project those as well.
user:
{
"$setDifference":
[{
"$map":
{
"input": "$user",
"as": "o",
"in":
{
$eq : ["$$o.id" , thisUser] //Updated here
}
}
},[false]
]
}
}
}
]);
The above query will give the object(s) matching the query in $match inside user array. Now you can access any field you want of that particular object.
'pizzaDay.user.confirm': function(){
return Groups.findOne({ _id: thisGroupeId }).user.confirm;
I resolved it using this:
Template.Pizzaday.helpers({
confirm: function(){
let isConfirm = Groups.findOne(
{_id: Session.get("idgroupe")}).user.filter(
function(v){
return v.id === Meteor.userId();
})[0].confirm;
return isConfirm;
},
});
But I still think that there is some much elegant way to do that.

Combining orderByChild and equalTo in Firebase queries

Given the following data structure:
{
"comments" : {
"-JcBbk64Gpm1SKoFHv8b" : {
"content" : "blah",
"createdAt" : 1417550954985,
"link" : "http%3A%2F%2Flocalhost%3A3000%2F",
"recommendedCount" : 0,
"replies" : {
"-JcBbk8gF_nQ_vjwag61" : true
},
"replyCount" : 1
},
"-JcBbk8gF_nQ_vjwag61" : {
"content" : "blah blah",
"createdAt" : 1417550955151,
"link" : "http%3A%2F%2Flocalhost%3A3000%2F",
"recommendedCount" : 0,
"replyCount" : 1,
"replyToComment" : "-JcBbk64Gpm1SKoFHv8b"
}
},
"links" : {
"http%3A%2F%2Flocalhost%3A3000%2F" : {
"author" : 5,
"commentCount" : 2,
"comments" : {
"-JcBbk64Gpm1SKoFHv8b" : true,
"-JcBbk8gF_nQ_vjwag61" : true
},
"createdAt" : 1417550954931,
"ratingCount" : 2,
"recommendedCount" : 32,
"score" : 91,
"title" : "A Christian vs. an Atheist: Round 2",
"url" : "http://localhost:3000/"
}
}
}
I would like to retrieve all the comments for a given link and sort them in reverse chronological order. I've gotten this far, but I can't figure out how to do the reverse sort because I've already used orderByChild to narrow down the results by link:
ref.orderByChild('link').equalTo(currentLink).on('value', function (snap) {
console.log(snapshot.val());
});
If I call orderByChild() a second time like this:
ref.orderByChild('link').equalTo(currentLink).orderByChild('createdAt').on('value', function (snap) {
console.log(snapshot.val());
});
it fails with this error message:
Uncaught Error: Query.orderByChild: You can't combine multiple orderBy calls.
I'm stumped. Any suggestions?
I encountered the same issues on my firebase project and I solved that like this.
Please take a look.
var formRef = firebase.child('links').child(currentLink);
formRef.orderByChild('createdAt').on('value', function (snap) {
console.log(snapshot.val());
});
It will works.
Best Regards.

Categories