Mongodb how to aggregate more different fields of the same collection with the same request? - node.js

another shock with express and mongodb, I would like to aggregate more different fields of the same collection with the same request called aggregate4, together with another request called query (query is full text) (aggregate is regex) but I'm having difficulty, example:
collection.aggregate([{$match:{
$text: {$search: '\"' + query.split(' ').join('\" \"') + '\"'}, //full text req.query
name_lower: new RegExp('^'+ aggregate1), // req.query.aggregate1 ok
surname_lower: new RegExp('^'+ aggregate2),//req.query.aggregate2 ok
sex_lower: new RegExp( aggregate3),//req.query.aggregate3 ok
$or:[{
note4_lower: new RegExp(aggregate4), //problem //req.query.aggregate4
note5_lower: new RegExp(aggregate4),//problem //req.query.aggregate4
}]
}]).limit(myLimit)
.toArray(function.......
note that note4_lower and note5_lower share the same request (aggregate4), unfortunately I only receive the note4.lower column in this case or note5.lower reversing the or and.
I tried to do the same with two $OR one for note4_lower and one for note5.lower, I also tried with collection.find as well as aggregate but nothing, or I receive only the "COLUMN" note4.lower or only the "COLUMN" note5.lower ... In both columns there are NULL fields (so either the field has note4.lower or note5.lower)
can someone help me?
I hope I explained myself well, thanks!

Related

Get multiple documents from collection using nodejs and mongodb

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/

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.

How to Match the string from collection after lookup with many collection using mongodb

Here My query
model.db.aggregate([{$lookup: {from: 'orders', localField: 'prod_id',
foreignField: '_id', as: 'Col'}},{$match:{$text:
{$search:'Sale'}}}).exec((err,data) => {console.log(data);}]);
but error showing "$match with $text is only allowed as the first pipeline !!"
I just want to lookup many collection then only I have to match'Search' in all the data what we joined(lookup) before.
mongoDb version: 4.0
Anybody have an idea ? need Help !
Thanks !!
These all are my Example collections:
collection 1 ->
organization ={'_id':ObjectId("5b110a7b84a0442030a1e9cf"),'Org_name':'dhoni institute','Estd':'1945'}
collection 2 -> players= {'_id':ObjectId("45110a7b84a3542030a1e9cf"),'_name':'Ms dhoni','Org_id' = ObjectId("5b110a7b84a0442030a1e9cf") }
I am searching the text string 'dhoni' in Db..then I want all the documents which contains word 'dhoni' from these collections.
How to do ?
db.players.aggregate([{$match:{$text:{$search:'dhoni'}}},
{
$lookup{from:'organization',localField:'_id',foreignField:'Org_id',as:'org'}
}
]).exec((err,data) => {}
this is my code It only matches the string from 'players' collection .I need matched 'players' collection documents as well as 'Organization' collection documents.
I cannot create new collection because after loopup data may be a huge data so
I cannot inserting new large data every time search
How to match the string after lookup ?
As explained in official mongodb documentation,
$text performs a text search on the content of the fields indexed with a text index.
But indexes are reachable only by the first stage of an aggregation query. That's the reason of your error message.
The only way i see for you to use $text/$search is to perform your aggregation (without match stage), adding an $out stage to output to a new collection, create a text index on that collection, and perform your find query with $text/$search criteria.
Hope it helps.

Node mongo bulk update, get the updated columns name

i have a bulk updation on mongodb in nodejs
i am facing the following scenario
user can update 20-30 fields at once, possibly he dont update all, he may change 1 or 2 or 5 or maybe all, i want to know exactly which are fields ie, whose value have be over-written with new values.
i need to know this because every field carry a weightage and if they update a particular field then i have to re-calculate the weightage of all the columns and assign it to the user
for example if
User.update({_id: user_id},{ $set : {key1:value,key2:value,key3:value... }})
now suppose key3 is over-written but key1 & key2 remains as it is,
so i want to know that key3 has been over-written.
how can i do that ?
if you use findOneAndUpdate function for updating, it's possible to retrieve document before updating, with that retrieved value you then can compare it with given document to find out witch fields has been updated.
The update function will be like this:
db.collection("Collection Name").findOneAndUpdate({"Find Query"},
{$set: {"Update Query"}},
{returnOriginal: true},
(err, res) => {
//... Some codes for comparing docs
});
The "returnOriginal" option makes the query to return updated document before update operation.

mongodb querying logic mongoose and nodejs

I apologize beforehand if this is a repeat question but i could not find any and i am a beginner.
I am making a filter for documents of db.
lets say I want to query 8 fields of documents written in a object
filter={key1:{lowerlimit: 'value', upperlimit:'value'},
key2:{lowerlimit: 'value', upperlimit:'value'},
key3:{lowerlimit: '', upperlimit:'value'},
key4:{lowerlimit: 'value', upperlimit:''},
key5:[],
key6:['value','value'],
key7:['value','value','value'],
key8:['value']}
now how do i write the logic of query so that the fields whose value is not specified will not get query. if i query all the parameters as they are. no documents will be displayed because 'key5' is empty array and using $in on it will result in no documents.
You'd want to remove the key5 field from your query object when it's empty.
if (!filter.key5.length) {
delete filter.key5;
}

Resources