Sequelize raw query not properly printed - node.js

I am trying to write query in sequelize but query is not working below is my query that I write in sequelize
var homePosts = db.postbox.findAll({
where: {
user_id: {
$or: {
$eq: id,
$in: [id]
}
}
},
attributes: ["user_posts_id"],
limit: 5
});
return homePosts;
Node js print result query
Executing (default): SELECT `user_posts_id` FROM `user_posts_boxes` AS `user_posts_boxes` WHERE `user_posts_boxes`.`user_id` = '[object Object]' LIMIT 5;
[]
It prints object instead of variable value and print the actual query that sequelize prepare.
My actual raw query is following which I actually want to convert into sequelize
SELECT `user_posts_id` FROM `user_posts_boxes` AS `user_posts_boxes` WHERE ( `user_posts_boxes`.`user_id` = '5' OR `user_posts_boxes`.`user_id` IN (select following_id from friend WHERE friend.follower_id = user_posts_boxes.user_id and friend.status='A' and friend.following_id=5)) LIMIT 5

I had the same issue with Sequelize 5. Use Symbol based operator and it should be fine https://github.com/sequelize/sequelize/issues/8417

Related

Implementing mongodb pagination along with match query?

I have user document as this
users = [
{
_id:'',
name:'jay',
email:'jay#gmail.com',
role: 'actor',
status: true // isActive
},
{
_id:'',
name:'ram',
email:'ram123#gmail.com',
role: 'electrician',
status: false // isActive
},
...... so on
]
I want to apply pagination and also some filters to retrieve data
filter = {
role: 'actor',
order: -1 //descending sort,
sortOn: 'name' // apply sort on name field
search: 'ja', // match the string starting with 'ja',
status: true,
size:25,
page: 1 // means documents from 1-25, page2 means 26-50
}
How can this be achieved?
I am using mongoose as well.
Using your filter object you can do something like this:
Use these steps to ensure a good pagination:
Sort by any value (to ensure not get random positions)
Skip by the number of pages
Limit by the number of elements into page
So, the query will be something like (not tested but you can see the idea):
const elementsPerPage = filter.size
const nSkip = elementsPerPage * filter.page
const sort = {[filter.sortOn]:filter.order}
YourModel.find({/*yourquery*/})
.limit(elementsPerPage)
.skip(nSkip)
.sort(sort)
Also, you can use filter values into your query, something like:
YourModel.find({
role: filter.role,
status:filter.status,
name:{ $regex: filter.search}
})
This query is like this example.
Also, is not defined what calues do you want to use, the condition etc, so, with this, you can use if/else to add or not values into query.
For example:
var query = {}
if(filter.search){
query.name = {$regex: filter.search}
}
So all together can be:
const elementsPerPage = filter.size
const nSkip = elementsPerPage * filter.page
const sort = {[filter.sortOn]:filter.order}
var query = {}
if(filter.search){
query.name = {$regex: filter.search}
}
if(filter.role){
query.role = filter.role
}
if(filter.status){
query.status = filter.status
}
YourModel.find(query)
.limit(elementsPerPage)
.skip(nSkip)
.sort(sort)
Note that this has not been tested, but as I've said before you can see the idea with this example.

MongoDB ObjectID query update

Hey guys i need to write a mongodb query to update a document i,e need to increment a field in docuemnt by 1, so for that i am using $inc operation but i am facing trouble in matching the document's key with the data sent by frontend
my db looks like this
_id:ObjectID("5ed4a86126663308549f816b")
title:svsbsbsssf
description:wdwwdwd
category:Object
_id:ObjectID("5ebc1144dde4f2974e209526")
label:World after Covid
category_id:1
url:world-after-covid
image:https://*****/assets/category-1590699874832.jpg
value:1
so this category is an Object and i am getting my category id from frontend, after converting that to ObjectID, i tried to match it like
let doc = await req.db
.collection("webinars")
.updateOne({category._id: categoryID }, { $inc: { listingViews: 1 } });
but the filter inside updateOne gives me error somehow the syntax isnt correct i guess
the error is like
Unexpected token, expected "," (17:26)
15 | let doc = await req.db 16 | .collection("webinars")
17 | .updateOne({category._id: categoryID }, { $inc: { listingViews: 1 } });
There is a syntax error in the updateOne filter object, the nested field path i.e category._id should be a string, something like this
// Notice the quotes around category._id
.updateOne({ "category._id": categoryID }, { $inc: { listingViews: 1 } });

Node Js sequelize select query by month

Am new in Node Js, In my Node Js project am using sequelize ORM with MySql database.
This is my query i want to write select query by month.
This is my query SELECT * FROM cubbersclosure WHERE MONTH(fromDate) = '04'
Here fromDate field type is date
This my code:
var fromDate = '2019-04-01'
var fromDateMonth = new Date(fromDate);
var fromMonth = (fromDateMonth.getMonth()+ 1) < 10 ? '0' + (fromDateMonth.getMonth()+1) : (fromDateMonth.getMonth()+1);
CubbersClosure.findAll({
where:{
// select query with Month (04)... //fromMonth
}
}).then(closureData=>{
res.send(closureData);
}).catch(error=>{
res.status(403).send({status: 'error', resCode:200, msg:'Internal Server Error...!', data:error});
});
Here fromMonth get only month from date, so i want to write code select query by month.
I'm not sure but what about try this?
where: {
sequelize.where(sequelize.fn("month", sequelize.col("fromDate")), fromMonth)
}
for those of you looking for postgres, this is a somewhat hacky way to make this work (make sure to unit test this):
const results = await models.users.findAll({
where: this.app.sequelize.fn('EXTRACT(MONTH from "createdAt") =', 3)
});
you can also take this a step further and query multiple attributes like so:
const results = await models.table.findAll({
where: {
[Op.and] : [
this.app.sequelize.fn('EXTRACT(MONTH from "createdAt") =', 3),
this.app.sequelize.fn('EXTRACT(day from "createdAt") =', 3),
]
}
});

MongoDB & Mongoose query returns null for aggregate $or search with non-matching field, returns individual searches or with undefined value omitted

I'm a bit confused by the behavior I'm seeing in a Mongoose/MongoDB query, as it seems that the $or operator is being treated as an $and
I have the following Collection Document that I am querying for:
{
"_id": {
"$oid": "5bd0d709ff8eef5d5325090f"
},
"audienceTrackingID": "3e66c213-fe0b-4096-a99c-558a6c349b4b",
"mainframeTrackingID": null,
"partner1TrackingID": "85c5f168-08da-44d3-bbef-fbb3b8392ded",
"__v": 0,
"contentFocus": "Cooking",
"ipRange": [
"29.142.127.151"
]
}
With the following query:
console.log(req.headers['x-original-ip']) // '29.142.127.151'
console.log(req.headers['x-audience-tracking-id']) // undefined
console.log(req.headers['x-partner-1-tracking-id']) // "85c5f168-08da-44d3-bbef-fbb3b8392ded"
const clientMatch = await Client.findOne({
$or: [{
ipRange: req.headers['x-original-ip'],
audienceTrackingID: req.headers['x-audience-tracking-id'],
partner1TrackingID: req.headers['x-partner-1-tracking-id'],
}]
})
console.log(clientMatch) // null
Somewhat puzzling, as querying for individual fields, as well as removing my query where the param is undefined within the actual query (req.headers['x-audience-tracking-id']) will produce results (Which makes me wonder, why is this acting like an AND and giving me null when one queryfield fails???)
// ALL QUERIES HIT AND RETURN A MATCH:
const tryThis = await Client.findOne({partner1TrackingID: req.headers['x-partner-1-tracking-id']})
const ipMatch = await Client.findOne({ipRange: req.headers['x-original-ip']})
const clientMatch = await Client.findOne({
$or: [{
ipRange: req.headers['x-original-ip'],
partner1TrackingID: req.headers['x-partner-1-tracking-id'],
}]
})
It makes no sense to me. Why would I need to omit a field which may not match from an $or operator in order to get a hit, when other fields match?
When you try to run your query you actually get:
query failed: cannot compare to undefined
See this here
This is one reason you get no results, another is that your $or query is not correct. You need to separate the or-ed items into separate objects for MongoDB:
So change your code to this:
const clientMatch = await Client.findOne({
$or: [
{ipRange: req.headers['x-original-ip']},
{audienceTrackingID: req.headers['x-audience-tracking-id'] || ''},
{partner1TrackingID: req.headers['x-partner-1-tracking-id']},
]
})

Distinct count with sequelize

I'm trying to get a distinct count with sequelize such as
'SELECT COUNT(DISTINCT(age)) AS `count` FROM `Persons` AS `Person`'
As long as I use a raw query, I get the desired result. However, as soon as I change to the sequelize count function, the query is broke in Postgres:
Person.count({distinct:'age'}).then(...);
results to
'SELECT COUNT(DISTINCT(*)) AS `count` FROM `Persons` AS `Person`'
which leads to a syntax error. Solutions described in different posts such as How to get a distinct count with sequelize? do not work, unless you add an include statement or a where clause which I do not have in this special case.
Does anybody know a proper solution for this?
You have to use Sequelize aggregation to make it worked correctly.
Model.aggregate(field, aggregateFunction, [options])
Returns: Returns the aggregate result cast to options.dataType, unless
options.plain is false, in which case the complete data result is
returned.
Example:
Person.aggregate('age', 'count', { distinct: true })
.then(function(count) {
//.. distinct count is here
});
Executing (default):
SELECT count(DISTINCT("age")) AS "count" FROM "persons" AS "person";
You can do it something like this :
models.User.findAll({
attributes: ['user_status',[sequelize.fn('COUNT', sequelize.col('user_status')), 'total']] ,
group : ['user_status']
});
That will return something like :
[
{ user_status : 1 , total : 2 },
{ user_status : 2 , total : 6 },
{ user_status : 3 , total : 9 },
...
]
Then you can loop through returned data and check of status
In latest version, you should be doing
Person.count({distinct:true, col: 'age'}).then(...);
See: http://docs.sequelizejs.com/class/lib/model.js~Model.html#static-method-count

Resources