mongo Queries With Multiple Expressions Specifying the Same Operator - node.js

Hello I am trying to perform the following query in my database
function getChat(nameChat, nameUser, callback) {
global.db.collection('chatUsers').find({
$and: [
{ $or : [ { nameChat: nameChat }, { nameChat: nameUser } ] },
{ $or : [ { nameUser: nameChat }, { nameUser: nameUser } ] }
]
}).sort({date: 1}).toArray(
function (err, docs) {
if (err) return console.log("algo deu errado" + err);
console.log("exit\n"+docs+nameUser);
callback(docs);
}
);}
But the query returns empty Here is an example of the objects I have in my chat Users collection:
{"_id":"5bc3e6d060d4da04dcd66517","nameChat":"Daciolo bolsominion","nameUser":"Mc Xhamps","date":"2018-10-14T17:22:00.000Z","msg":"VocĂȘ pertence a URSAL"}
{"_id":"5bc52fc3b878631f84c77c41","nameChat":"Mc Xhamps","nameUser":"Daciolo bolsominion","date":"2018-10-01T17:25:00.000Z","msg":"E ai, bora ser Presidente"}
To be clear I would like my query to return all objects that name Chat or name User are present in the same object
This query with this is only returning empty objects.

Hey Erik change the and with or you will get required result.
global.db.collection('chatUsers').find({
$or: [
{ $or : [ { nameChat: nameChat }, { nameChat: nameUser } ] },
{ $or : [ { nameUser: nameChat }, { nameUser: nameUser } ] }
]
}).sort({date: 1})

Related

How to add or remove a element in double nested array?

Example of the document:
{
postId:'232323',
post:'This is my first post',
commentsOnPost:[
{
commentId:'232323_8888',
comment:'Congrats',
repliesOnPost:[
{
replyId:'232323_8888_66666',
reply:'Thanks',
likesOnReply:['user1','user5','user3'],
}
]
}
]
}
I want to add userid in likesOnReply if users do not exist in likesOnReply, similarly remove userid from likesOnReply if exist.
I have tried like this but not working properly
await collection('post').findOneAndUpdate(
{
postId: postId,
'commentsOnPost.commentId': commentId,
'commentsOnPost.repliesOnPost.replyId': replyId
},
{
$push: { 'commentsOnPost.$[].repliesOnPost.$.likes': userid },
},
);
There is no straight way to do both the operation to pull or push in a single query,
There are 2 approaches,
1) Find and update using 2 queries:
use arrayFilters to updated nested array elements
$push to insert element
$pull to remove element
var post = await collection('post').findOne({
posted: postId,
ommentsOnPost: {
$elemMatch: {
commentId: commentId,
repliesOnPost: {
$elemMatch: {
replyId: replyId
likesOnReply: userid
}
}
}
}
});
var updateOperator = "$push";
// FOUND USER ID THEN DO REMOVE OPERATION
if (post) updateOperator = "$pull";
// QUERY
await collection('post').updateOne(
{ postId: postId },
{
[updateOperator]: {
"commentsOnPost.$[c].repliesOnPost.$[r].likesOnReply": userid
}
},
{
arrayFilters: [
{ "c.commentId": commentId },
{ "r.replyId": replyId }
]
}
)
Playground
2) Update with aggregation pipeline starting from MongoDB 4.2:
$map to iterate loop of commentsOnPost array check condition if commentId match then go to next process otherwise return existing object
$mergeObjects to merge current object with updated fields
$map to iterate loop of repliesOnPost array and check condition if replyId match then go to next process otherwise return an existing object
check condition for likesOnReply has userid then do remove using $filter otherwise insert using $concatArrays
await collection('post').findOneAndUpdate(
{ postId: "232323" },
[{
$set: {
commentsOnPost: {
$map: {
input: "$commentsOnPost",
in: {
$cond: [
{ $eq: ["$$this.commentId", commentId] },
{
$mergeObjects: [
"$$this",
{
repliesOnPost: {
$map: {
input: "$$this.repliesOnPost",
in: {
$cond: [
{ $eq: ["$$this.replyId", replyId] },
{
$mergeObjects: [
"$$this",
{
likesOnReply: {
$cond: [
{ $in: [userid, "$$this.likesOnReply"] },
{
$filter: {
input: "$$this.likesOnReply",
cond: { $ne: ["$$this", userid] }
}
},
{
$concatArrays: ["$$this.likesOnReply", [userid]]
}
]
}
}
]
},
"$$this"
]
}
}
}
}
]
},
"$$this"
]
}
}
}
}
}]
)
Playgorund

how can I get one document in mongoose(mongoDB)?

I want to return one index's object of the array,
but when I query, It returns to me that all of the documents.
This is my Schema(userTb)
const userTbSchema = new Schema({
_id: mongoose.Schema.Types.ObjectId,
userId: String,
folders: [
{
folderTitle: String,
}
]
}
and this is the result of the query of my Schema(userTb).
{
"_id": "5fc4c13f32ab3174acb08540",
"userId": "go05111",
"folders": [
{
"_id": "5fb7b0473fddab615456b166",
"folderTitle": "first-go"
},
{
"_id": "5fb7b0473fddab615456b16b",
"folderTitle": "second-go"
}
]
}
I want to get the only { "folderTitle" : "first-go" } folder's object, like...
{
"_id": "5fb7b0473fddab615456b166",
"folderTitle": "first-go"
}
so I query like this
router.get('/folder/:folderId', (req, res, next) => {
UserTb.find({ folders : { "$elemMatch" : { _id : req.params.folderId} } })
.exec()
.then(docs => {
res.status(200).json({
docs
});
})
.catch(err => {
res.status(500).json({
error: err
});
});
});
but the result is nothing changed.
I tried a few different ways, but it didn't work out.
how can I fix it?
please help me...
Try this (live version):
UserTb.aggregate({
$match: {
"folders._id": req.params.folderId }
},
{
$project: {
folders: {
$filter: {
input: "$folders",
as: "f",
cond: {
$eq: [
"$$f.folderTitle",
"first-go"
]
}
}
},
_id: 0
}
})
It will retrieve folders:[{...}] this will be easy to tackle using JS, and quicker.
Mechanism
Match only documents containing _id:folderId
project only the inner document

How to query an object with a specific key/value pair in an array with Mongodb?

This is my data structure:
{
studentName: 'zzz',
teachers: [
{
teacherName: 'xxx',
feedbacks: []
}, {
teacherName: 'yyy',
feedbacks: []
}
]
}
Now I am trying to code a query to add an 'feedback' object to the 'feedbacks' array that belongs to the teacher named 'yyy'.
await collection.updateOne({
studentName: 'zzz',
teachers: {
$elemMatch: {
teacherName: {
$eq: 'yyy'
}
}
}
}, {
$push: {
'teachers.$.feedbacks': {}
}
})
The query part is faulty somehow. If I change '$' to 0 or 1, then the code works finally. Otherwise, the object cannot be pushed.
This update works fine, adds the string element "Nice work" to the teachers.feedbacks nested array.
db.test.updateOne(
{
studentName: "zzz",
"teachers.teacherName": "yyy"
},
{ $push: { "teachers.$.feedbacks" : "Nice work" } }
)
The $elemMatch syntax is not required, as the query condition for the array elements is for a single field.
The updated document:
{
"studentName" : "zzz",
"teachers" : [
{
"teacherName" : "xxx",
"feedbacks" : [ ]
},
{
"teacherName" : "yyy",
"feedbacks" : [
"Nice work"
]
}
]
}

pipeline with $match not work as per expectation on mongodb

I have tried to do somthing like this join and search. I'm trying to do a search with in side pipeline with $match, but the issue is that $match is not working.
it is not searching or join two collections.
SELECT * FROM `post`
Left JOIN postcat ON post.id=postcat.postid
Left JOIN catagory ON postcat.catid=catagory.id
WHERE
post_name LIKE '%a%'
OR post_data LIKE '%some data%'
OR tags LIKE '%some data%'
OR post_url LIKE '%some data%'
This is my collection info
Post
{
"_id" : ObjectId("5d29bd7609f28633f38ccc13"),
"postname" : "this is some data",
"tags" : "Damita,Caro",
"postdata" : "Berry Roseline Lira Cristy Hedi Clem Nerissa ",
"catagory" : [ {
"catagory_id" : [
ObjectId("5d29bd7509f28633f38ccbfd")
]
}, {
"catagory_id" : [
ObjectId("5d29bd7509f28633f38ccbfd")
]
}
],
"createby" : "5d22f712fe481b2a9afda4aa"
} ..........
category
{
"_id" : ObjectId("5d29bc271a68fb333531f6a1"),
"catagory_name" : "Katharine",
"catagory_description" : "Katharine"
}
The code i have tried so far:
var search_data = "some data";
var search_limit = 10;
var search_skip = 0;
db.collection.aggregate([
{
$lookup: {
let: {
post_id: "$catagory.catagory_id" ,
postname: "$postname",
posturl: "$posturl" ,
postdata: "$postdata" ,
tags: "$tags"
},
from: 'catagories',
pipeline: [
{
$match: {
$expr: {
$and: [
{ $eq: ["$_id", "$$post_id"] },
{
$or: [
{"$$catagory_name": { $regex: new RegExp(search_data, 'i')}},
{"$$postname": { $regex: `^${search_data}` } },
{"$$posturl": { $regex: new RegExp(search_data, 'i') }},
{"$$postdata": { $regex: new RegExp(search_data, 'i') }},
{"$$tags": { $regex: new RegExp(search_data, 'i') }}
]
}
]
}
}
}
],
as: "catagories_data"
}
},
{ $limit : search_limit },
{ $skip : search_skip },
{ $group : { _id : "$_id", postname: { $push: "$postname" } } }
]).expla(function (err, data_post)
{
console.log(err);
console.log(data_post);
})
i have no idea how to fix it. any suggestion on it

Mongoose $or query with $near doesn't seem to work

I'm trying to run an $or query but whenever I use $near in one of the $or clauses, the query returns 0 results.
Here is my code:
params = { $or: [
{ loc: { '$near': {
'$geometry': {
type : "Point" ,
coordinates : [ -0.127500 , 51.507220 ]
},
'$maxDistance': 1000
} } },
{ categories: { $in: ['Services'] } }
] };
var query = Activity.find(params).populate({path: '_place'});
query.limit(10).exec('find', function(err, items) {
...
});

Resources