All of a sudden Select doesn't work Your query doesn't seem to be wrong Select doesn't work and it's hard to insert a pipeline I need it for debugging Why doesn't it work?
Windows mongodb compass management tool Aggregations -> Select query add does not work
image link
https://i.stack.imgur.com/z609k.png
mycode
[
{'$match':{'month':202202}},
{
'$lookup':{
'from':'stat_ad_conversion',
'let':{'master_id':'$master_id','campaign_id':'$campaign_id','biz_id':'$biz_id','yyyy':'$yyyy','mm':'$mm'},
'pipeline':[
{
'$match':{
'$expr':{
'$and':[
{'$eq':['$master_id','$$master_id']},
{'$eq':['$campaign_id','$$campaign_id']},
{'$eq':['$biz_id','$$biz_id']},
{'$eq':['$yyyy','$$yyyy']},
{'$eq':['$mm','$$mm']}
]
}
}
}
],
'as':'t1'
}
},
{'$unwind':{'path':'$t1','preserveNullAndEmptyArrays':true}},
{
'$group':{
'_id':{'master_id':'$master_id','campaign_id':'$campaign_id','biz_id':'$biz_id','yyyy':'$yyyy','mm':'$mm'},
'exposecount':{'$sum':'$exposecount'},
'clickcount':{'$sum':'$clickcount'},
'cost':{'$sum':'$cost'},
'mm':{'$first':'$mm'}
}
},
{
'$group':{
'_id':{'master_id':'$t1.master_id','campaign_id':'$t1.campaign_id','biz_id':'$t1.biz_id','keyword_id':'$t1.keyword_id','yyyy':'$t1.yyyy','mm':'$t1.mm'},
'count':{'$sum':'$conversion_count'},
'keywordcount':{'$sum':1},
'conversioncost':{'$sum':'$t1.conversion_count'},
'directcount':{'$sum':{'$switch':{'branches':[{'case':{'$eq':['$t1.conversion_method',1]},'then':'$t1.conversion_count'}],'default':0}}},
'indirectcount':{'$sum':{'$switch':{'branches':[{'case':{'$eq':['$t1.conversion_method',2]},'then':'$t1.conversion_count'}],'default':0}}},
'conversioncost':{'$sum':'$t1.sales_conversion'},
'conversiondirectcost':{'$sum':{'$switch':{'branches':[{'case':{'$eq':['$t1.conversion_method',1]},'then':'$t1.sales_conversion'}],'default':0}}},
'conversionindirectcost':{'$sum':{'$switch':{'branches':[{'case':{'$eq':['$t1.conversion_method',2]},'then':'$t1.sales_conversion'}],'default':0}}}
}
},
{
'$merge':{
'into':'finish_period_month_1',
'on':'_id',
'whenMatched':'replace',
'whenNotMatched':'insert'
}
}
]
Creating and executing a normal pipeline query Select does not work
Only No Preview Documents no results are coming out
Related
I want to add the cost of a particular month for a specific category. This is my object stored in MongoDB :
{
"2022":{
"January":{
"Food":30,
"Traveling":0,
"Medical":0,
},
"Feburary":{
"Food":1000,
"Traveling":0,
"Medical":50,
},
"March":{
"Food":100,
"Traveling":20,
"Medical":10,
}
}
}
Now, I am making a patch request:
{
"month":"March",
"monthData":[70,45,100]
}
Now, I want my data to be updated like this:
{
"2022":{
"January":{
"Food":30,
"Traveling":0,
"Medical":0,
},
"Feburary":{
"Food":1000,
"Traveling":0,
"Medical":50,
},
"March":{
"Food":170,
"Traveling":65,
"Medical":110,
}
}
}
What query should I write using Model.findAndUpate(filter,object) so that above thing works.
Your patch request looks to me like this:
db.collection.update({},
{
"$inc": {
"2022.March.Food": 70,
"2022.March.Traveling": 45,
"2022.March.Medical": 100
}
})
Playgroud
I hate to risk asking a duplicate question, but perhaps this is different from Passing Variables to a MongoDB View which didn't have any clear solution.
Below is a query to find the country for IP Address 16778237. (Outside the scope of this query, there is a formula that turns an IPV4 address into a number.)
I was wondering if we could abstract away this query out of NodeJS code, and make a view, so the view could be called from NodeJS. But the fields ipFrom and ipTo are indexed to get the query to run fast against millions of documents in the collection, so we can't return all the rows to NodeJS and filter there.
In MSSQL maybe this would have to be a stored procedure, instead of a view. Just trying to learn what is possible in MongoDB. I know there are functions, which are written in JavaScript. Is that where I need to look?
db['ip2Locations'].aggregate(
{
$match:
{
$and: [
{
"ipFrom": {
$lte: 16778237
}
},
{
"ipTo": {
$gte: 16778237
}
},
{
"active": true
}
],
$comment: "where 16778237 between startIPRange and stopIPRange and the row is 'Active',sort by createdDateTime, limit to the top 1 row, and return the country"
}
},
{
$sort:
{
'createdDateTime': - 1
}
},
{
$project:
{
'countryCode': 1
}
},
{
$limit: 1
}
)
Part 2 - after more research and experimenting, I found this is possible and runs with success, but then see trying to make a view below this query.
var ipaddr = 16778237
db['ip2Locations'].aggregate(
{
$match:
{
$and: [
{
"ipFrom": {
$lte: ipaddr
}
},
{
"ipTo": {
$gte: ipaddr
}
},
{
"active": true
}
],
$comment: "where 16778237 between startIPRange and stopIPRange and the row is 'Active',sort by createdDateTime, limit to the top 1 row, and return the country"
}
},
{
$sort:
{
'createdDateTime': - 1
}
},
{
$project:
{
'countryCode': 1
}
},
{
$limit: 1
}
)
If I try to create a view with a "var" in it, like this;
db.createView("ip2Locations_vw-lookupcountryfromip","ip2Locations",[
var ipaddr = 16778237
db['ip2Locations'].aggregate(
I get error:
[Error] SyntaxError: expected expression, got keyword 'var'
In the link I provided above, I think the guy was trying to figure how the $$user-variables work (no example here: https://docs.mongodb.com/manual/reference/aggregation-variables/). That page refers to $let, but never shows how the two work together. I found one example here: https://www.tutorialspoint.com/mongodb-query-to-set-user-defined-variable-into-query on variables, but not $$variables. I'm
db.createView("ip2Locations_vw-lookupcountryfromip","ip2Locations",[
db['ip2Locations'].aggregate(
...etc...
"ipFrom": {
$lte: $$ipaddr
}
I tried ipaddr, $ipaddr, and $$ipaddr, and they all give a variation of this error:
[Error] ReferenceError: $ipaddr is not defined
In a perfect world, one would be able to do something like:
get['ip2Locations_vw-lookupcountryfromip'].find({$let: {'ipaddr': 16778237})
or similar.
I'm getting that it's possible with Javascript stored in MongoDB (How to use variables in MongoDB query?), but I'll have to re-read that; seems like some blogs were warning against it.
I have yet to find a working example using $$user-variables, still looking.
Interpretation
You want to query a view from some server side code, passing a variable to it.
Context
Can we use an external variable to recompute a View? Take the following pipeline:
var pipeline = [{ $group:{ _id:null, useless:{ $push:"$$NOW" } } }]
We can pass system variables using $$. We can define user variables too, but the user defined variables are made out of:
Collection Data
System Variables.
Also, respect to your Part2:
A variable var variable="what" will be computed only once. Redefine variable="whatever" makes no difference in the view, it uses "what".
Conclusion
Views can only be re-computed with system variables, or user variables dependant on those system variables or collection data.
Added an answer to the post you link too.
I have a database like this:
[
{
"universe":"comics",
"saga":[
{
"name":"x-men",
"characters":[
{
"character":"wolverine",
"picture":"618035022351.png"
},
{
"character":"cyclops",
"picture":"618035022352.png"
}
]
}
]
},
{
"universe":"dc",
"saga":[
{
"name":"spiderman",
"characters":[
{
"character":"venom",
"picture":"618035022353.png"
}
]
}
]
}
]
and with this code I manage to update one of the objects in my array. specifically the object where character: wolverine
db.mydb.findOneAndUpdate({
"universe": "comics",
"saga.name": "x-men",
"saga.characters.character": "wolverine"
}, {
$set: {
"saga.$[].characters.$[].character": "lobezno",
"saga.$[].characters.$[].picture": "618035022354.png",
}
}, {
new: false
}
)
it returns all my document, I need ONLY the document matched
I would like to return the object that I have updated without having to make more queries to the database.
Note
I have been told that my code does not work well as it should, apparently my query to update this bad, I would like to know how to fix it and get the object that matches these search criteria.
In other words how can I get this output:
{
"character":"wolverine",
"picture":"618035022351.png"
}
in a single query using filters
{
"universe": "comics",
"saga.name": "x-men",
"saga.characters.character": "wolverine"
}
My MongoDB knowledge prevents me from correcting this.
Use the shell method findAndModify to suit your needs.
But you cannot use the positional character $ more than once while projecting in MongoDb, so you may have to keep track of it yourself at client-side.
Use arrayFilters to update deeply nested sub-document, instead of positional all operator $[].
Below is a working query -
var query = {
universe: 'comics'
};
var update = {
$set: {
'saga.$[outer].characters.$[inner].character': 'lobezno',
'saga.$[outer].characters.$[inner].picture': '618035022354.png',
}
};
var fields = {
'saga.characters': 1
};
var updateFilter = {
arrayFilters: [
{
'outer.name': 'x-men'
},
{
'inner.character': 'wolverine'
}
]
};
db.collection.findAndModify({
query,
update,
fields,
arrayFilters: updateFilter.arrayFilters
new: true
});
If I understand your question correctly, your updating is working as expected and your issue is that it returns the whole document and you don't want to query the database to just to return these two fields.
Why don't you just extract the fields from the document returned from your update? You are not going to the database when doing that.
var extractElementFromResult = null;
if(result != null) {
extractElementFromResult = result.saga
.filter(item => item.name == "x-men")[0]
.characters
.filter(item => item.character == "wolverine")[0];
}
Hi all I am very new in mongodb and I have some problems when I try to do some find in a collections I hope so someone can help me.
Imagine I have the following collection:
db.fechasCambio.insert(
{
columns:[
'Divisa',
'05/10/2015',
'02/10/2015',
'01/10/2015',
'30/09/2015',
'29/09/2015',
'28/09/2015',
'25/09/2015',
'24/09/2015',
],
data:[
{
'Divisa':'USD',
'05/10/2015':'11236',
'02/10/2015':'1116',
'01/10/2015':'11153',
'30/09/2015':'11203',
'29/09/2015':'11204',
'28/09/2015':'1117',
'25/09/2015':'11151',
'24/09/2015':'11241'
},
{
'Divisa':'BGD',
'05/10/2015':'19558',
'02/10/2015':'19558',
'01/10/2015':'19558',
'30/09/2015':'19558',
'29/09/2015':'19558',
'28/09/2015':'19558',
'25/09/2015':'19558',
'24/09/2015':'19558'
},
{
'Divisa':'CYP',
'05/10/2015':'0',
'02/10/2015':'0',
'01/10/2015':'0',
'30/09/2015':'0',
'29/09/2015':'0',
'28/09/2015':'0',
'25/09/2015':'0',
'24/09/2015':'0'
}
]
}
) c
Now I want do some find inside the collections for example:
A-I want to bring me all currencies search by date range 05/10/2015 to 01/10/2015 then I need that return something like this:
{
columns:[
'Divisa',
'05/10/2015',
'02/10/2015',
'01/10/2015',
],
data:[
{
'Divisa':'USD',
'05/10/2015':'11236',
'02/10/2015':'1116',
'01/10/2015':'11153',
},
{
'Divisa':'BGD',
'05/10/2015':'19558',
'02/10/2015':'19558',
'01/10/2015':'19558',
},
{
'Divisa':'CYP',
'05/10/2015':'0',
'02/10/2015':'0',
'01/10/2015':'0',
}
]
}
I want to know what is the structure of the find that I need to use for have a result similar.
B-Also I need to know how do a find that return all the information related with a currency, for example I want searh all releated with the currency 'USD', I need return something similar to:
{
columns:[
'Divisa',
'05/10/2015',
'02/10/2015',
'01/10/2015',
'30/09/2015',
'29/09/2015',
'28/09/2015',
'25/09/2015',
'24/09/2015',
],
data:[
{
'Divisa':'USD',
'05/10/2015':'11236',
'02/10/2015':'1116',
'01/10/2015':'11153',
'30/09/2015':'11203',
'29/09/2015':'11204',
'28/09/2015':'1117',
'25/09/2015':'11151',
'24/09/2015':'11241'
}
]
}
I want to know what is the structure of the find that I need to use for have a result similar.
C-And finally I need to know how do a find that return all the information related with a value, for example I want search all the information with value of 0 between 12000, I need return something similar to:
{
columns:[
'Divisa',
'05/10/2015',
'02/10/2015',
'01/10/2015',
'30/09/2015',
'29/09/2015',
'28/09/2015',
'25/09/2015',
'24/09/2015',
],
data:[
{
'Divisa':'USD',
'05/10/2015':'11236',
'02/10/2015':'1116',
'01/10/2015':'11153',
'30/09/2015':'11203',
'29/09/2015':'11204',
'28/09/2015':'1117',
'25/09/2015':'11151',
'24/09/2015':'11241'
},
{
'Divisa':'CYP',
'05/10/2015':'0',
'02/10/2015':'0',
'01/10/2015':'0',
'30/09/2015':'0',
'29/09/2015':'0',
'28/09/2015':'0',
'25/09/2015':'0',
'24/09/2015':'0'
}
]
}
I want to know what is the structure of the find that I need to use for have a result similar.
I tried a lot of time to figure out getting an OR clause working in sails without success.
I am using Sails-MySql adapter.
Have anyone of you done anything like this already? I would appreciate some help.
Basically this is what I want to do:
Do an OR clause on a set of fields along with an AND on another set of fields.
Something like this:
FdbDevice
.find()
.where(or:
[
{ deviceCategory: “cardiology valve bioprosthesis” },
{ deviceCategory: “nephrology haemodialysis catheter” }
]
})
.where(
{ catalogNumber : “Z286004” },
{ modelNumber: “Z286004” }
)
.exec
In this particular case, here is how I would do it:
// Each element in the array is treated as 'or'
var possibleDeviceCategories = [
'cardiology valve bioprosthesis',
'nephrology haemodialysis catheter'
];
FdbDevice
.find({
deviceCategory: possibleDeviceCategories,
catalogNumber: 'Z286004',
modelNumber: 'Z286004'
})
.exec(cb);
Check out the docs for more informations about the Waterline's query language.
you can try something like that, into the find:
FdbDevice
.find({or:
[
{ deviceCategory: “cardiology valve bioprosthesis” },
{ deviceCategory: “nephrology haemodialysis catheter” }
]
})
.where(
{ catalogNumber : “Z286004” },
{ modelNumber: “Z286004” }
)