Boolean attribute for Waterline model - node.js

I have a MySQL database and a Waterline model for a fairly simple record: Todo. It's straight-forward as we're using it for proof-of-concept for a Sails.js API.
CREATE TABLE `Todo` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`TodoItem` varchar(200) NOT NULL,
`Completed` bit(1) NOT NULL DEFAULT b'0',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 COMMENT=' ';
I have the model set up in this way:
module.exports = {
connection: 'companyMySql',
tableName: 'Todo',
attributes: {
ID: {
type: 'integer',
autoIncrement: true,
primaryKey: true
},
TodoItem: {
type: 'string',
required: true
},
Completed: {
type: 'boolean',
defaultsTo: 'false',
size: 1,
boolean: true
}
},
autoCreatedAt: false,
autoUpdatedAt: false,
autoPK: false
};
The problem I'm having is that the auto-created API for Todo creates a bunch of extra cruft in the 'Completed' field, and I'm trying to find out how I remove it. I'm expecting a boolean value, but I could definitely work with 0/1, or string literals, but that's not what I'm getting. I've tried various validation on the field, like 'min: 0, max: 1', but that has not changed the result.
Here is the results of a retrieval of a single record:
{
"ID": 1,
"TodoItem": "Create Todo API",
"Completed": {
"0": 1,
"length": 1,
"parent": [
100,
0,
0,
0,
3,
83,
69,
76,
69,
67,
96,
46,
96,
73,
68,
96,
44,
32,
96,
116,
111,
100,
111,
96,
// This continues on for quite some time
],
"offset": 2128 // This value increases each time I call a GET until it gets to ~8000, then it resets to ~500
}
}
So does anyone have any idea on what I can do to get a straight-forward boolean value out of this?

After some further testing, I was able to get a boolean value to work as expected by using TINYINT(1) for my column datatype. Once I did that, this model worked as I expected it to:
Completed: {
type: 'boolean',
defaultsTo: false,
boolean: true
}
This still doesn't seem ideal, but it was a solution for my purposes.

Related

Node JS, Mongoose How to query schema via aggregate?

I am new to using MongoDB and I am trying to update update my document using aggregate $set pipeline. However I have been trying this for a few days and there is still no success. I am trying to update by querying ObjectId and replacing matched result (singular) with the key value pair I specified. I tested the aggregate on Mongo Compass and it works. Does anyone know how to use aggregate for Node JS?
updateOne query I tried
let query = {"_id": ObjectId('theObjectIamUpdating')};
response = await newForm.updateOne(query, payload);
aggregate query I tried
response = await newForm.updateOne([
{$match: {"_id": ObjectId(update_id)}},
{$set: {
"data.velo": [
[1, 2, 3], [5, 7]
]
}}
]);
newForm Mongoose Schema
data: {
date: {
type: Array,
required: false,
trim: true,
},
speed: {
type: Array,
required: false,
trim: true,
},
velo: {
type: Array,
required: false,
trim: true,
}
},
calc: {
date: {
type: Array,
required: false,
trim: true,
},
speed: {
type: Array,
required: false,
trim: true,
},
velo: {
type: Array,
required: false,
trim: true,
}
}
UPDATE
I my updateOne() has succeeded, but my documents are not getting updated.
the result I got after logging response that I awaited
Data received {
acknowledged: true,
modifiedCount: 0,
upsertedId: null,
upsertedCount: 0,
matchedCount: 0
}
POST /api/compute/calculate 200 16 - 79.821 ms
Additionally, this is the MongoDB aggregate that worked when I tried on Mongo Compass
pipeline = $match > $set
**$match**
{
"_id": ObjectId('62e2295060280132dbcee4ae')
}
**$set**
{
"data.velo": [
[1, 2, 3], [5, 7]
]
}
where velo is one of the key value pairs in data, and the set result replaced only the data in data.velo.
As prasad_ mentioned in the comment section, I indeed found some mistakes with regards to my syntax of updateOne().
Correct Syntax for updateOne()
let response = await Form_csv_metadata2.updateOne({ '_id': [update_id] }, [
{//delete this line $match: {"_id": ObjectId(update_id)},
$set: {
"data.velo": [[1, 2, 3], [5, 7]]
}}
]);
As the official document has mentioned the parameters are: Query, UpdateData and Option. I made the mistake as my query was placed in my UpdateData() param (the $match). It should have been a param by itself as a query (query uses same syntax as find()). Another note is that if I were to use a pipeline aggregate, it should have been { $match: {...}, $set: {...} } instead of { {$match: {...}}, {$set: {...}} }

Sequelize.select returns wrong dates

I am attempting to create a web (react/sequelize) front end to an existing database.
When I perform a select from the database the returns results in sequelize have the date as off by 1 (-1).
Here is the SQL and code used to get the data:
let sql1 = 'SELECT count(RECEIVED_DATE) as CallCount, CAST(RECEIVED_DATE AS DATE) as CallDate FROM TowCalls WHERE OFFICE_ID = ? AND (RECEIVED_DATE BETWEEN dateadd(day,?, GETDATE()) AND GETDATE()) group by CAST(RECEIVED_DATE AS DATE) ORDER BY CAST(RECEIVED_DATE AS DATE)';
models.sequelize.query(sql1, { replacements: [id, -7], type: models.sequelize.QueryTypes.SELECT })
.then(function(summary) {
When I output summary to the console I get:
[
{ CallCount: 22, CallDate: '2020-12-16' },
{ CallCount: 36, CallDate: '2020-12-17' },
{ CallCount: 20, CallDate: '2020-12-18' },
{ CallCount: 12, CallDate: '2020-12-19' },
{ CallCount: 28, CallDate: '2020-12-20' },
{ CallCount: 13, CallDate: '2020-12-21' },
{ CallCount: 1, CallDate: '2020-12-22' }
]
When I use the same query in SQL Server itself I get the same counts, but all the dates are +1.
Although I never specifically set it, I believe the dates are in SQL in EST timezone.
All the users of the database are in the same timezone so I never had to worry about tracking any changes.

Is there a way to return a document body after indexing?

I am looking to return the full contents of a document after it is indexed. Elastic only returns:
{
_index: 'doc-dataset',
_type: 'my-doc',
_id: 'AVt8nyuxRNHpCQ5APUtx',
_version: 1,
result: 'created',
_shards: { total: 2, successful: 1, failed: 0 },
created: true,
status: 201
}
I would like it to return something like:
{
_index: 'doc-dataset',
_type: 'my-doc',
_id: 'AVt8nyuxRNHpCQ5APUtx',
_version: 1,
result: 'created',
_shards: { total: 2, successful: 1, failed: 0 },
created: true,
status: 201,
source:{
prop: value,
prop: value,
...
prop: value
}
Is this possible?
GET /index_name/_search
will give you all the documents along with properties and its respective values.

MongoDB MapReduce weird bug

I'm trying this simple MapReduce operation:
function map() {
var gameDay = Math.floor((this.matchCreation - 1427846400000) / 86400000) + 1; // day of april 2015 when the game was played
this.teams.forEach (function (team){
**team.bans.forEach(function (ban){** // says bans is undefined
var value ={
banned : 1,
firstBanned: ( ((ban.pickTurn == 1) || (ban.pickTurn == 2))? 1 : 0 )
}
emit({championId: ban.championId,
day: Number(gameDay)}, value);
emit({championId: ban.championId,
day: "all"}, value);
});
});
}
function reduce(key, values) {
var a = values[0];
for(var i = 1 ; i<values.length ; i++){
var b = values[i]; // will merge 'b' into 'a'
a.banned += (b.banned? b.banned : 0);
a.firstBanned += (b.firstBanned? b.firstBanned : 0);
for (var attrname in b){
if(attrname != "banned" && attrname != "firstBanned")
a[attrname] = b[attrname];
}
}
return a;
}
matchesCollection.mapReduce(map, reduce, {
out: { reduce: "mapReduceResults" }
}, function (err, data){
if(err)
return callback (err);
callback (null, "OK");
});
It used to work before, but just when I tried to deploy the app after testing for a while, it seems to fail in this line: team.bans.forEach(function (ban){, says team.bans is undefined, although every one of the documents has a "teams" array and a "bans" array inside of each object in it, I even double checked it by querying the database and there is no document in which those fields dont exist.
So weird. The reduce function is a bit more complex but it seems to work alright, yet the map one (unlike Reduce, its supposed to be called just once per original document, right?) throws this unexplainable error. Could anyone give me some insight?
Sample input:
{
"_id": {
"$oid": "5531a63f2a3f135c11ed14a8"
},
"matchId": 1778704162,
"region": "NA",
"platformId": "NA1",
"matchMode": "CLASSIC",
"matchType": "MATCHED_GAME",
"matchCreation": 1427864425511,
"matchDuration": 1431,
"queueType": "URF_5x5",
"mapId": 11,
"season": "SEASON2015",
"matchVersion": "5.6.0.194",
"participants": [
{
"teamId": 100,
"spell1Id": 12,
"spell2Id": 4,
"championId": 81,
"highestAchievedSeasonTier": "SILVER",
"timeline": [],
"masteries": [],
"stats": {
"winner": false,
"champLevel": 19,
"item0": 1037,
"item1": 3078,
"item2": 3117,
"item3": 3035,
"item4": 3072,
"item5": 1038,
"item6": 3340,
"kills": 7,
"doubleKills": 1,
"tripleKills": 0,
"quadraKills": 0,
"pentaKills": 0,
"unrealKills": 0,
"largestKillingSpree": 3,
"deaths": 15,
"assists": 9,
"totalDamageDealt": 103191,
"totalDamageDealtToChampions": 22148,
"totalDamageTaken": 32924,
"largestCriticalStrike": 669,
"totalHeal": 2263,
"minionsKilled": 97,
"neutralMinionsKilled": 1,
"neutralMinionsKilledTeamJungle": 1,
"neutralMinionsKilledEnemyJungle": 0,
"goldEarned": 13923,
"goldSpent": 13273,
"combatPlayerScore": 0,
"objectivePlayerScore": 0,
"totalPlayerScore": 0,
"totalScoreRank": 0,
"magicDamageDealtToChampions": 6082,
"physicalDamageDealtToChampions": 15803,
"trueDamageDealtToChampions": 263,
"visionWardsBoughtInGame": 0,
"sightWardsBoughtInGame": 0,
"magicDamageDealt": 45997,
"physicalDamageDealt": 56651,
"trueDamageDealt": 543,
"magicDamageTaken": 25249,
"physicalDamageTaken": 7490,
"trueDamageTaken": 184,
"firstBloodKill": false,
"firstBloodAssist": false,
"firstTowerKill": false,
"firstTowerAssist": false,
"firstInhibitorKill": false,
"firstInhibitorAssist": false,
"inhibitorKills": 0,
"towerKills": 4,
"wardsPlaced": 2,
"wardsKilled": 0,
"largestMultiKill": 2,
"killingSprees": 1,
"totalUnitsHealed": 1,
"totalTimeCrowdControlDealt": 98
},
"participantId": 1,
"runes": []
},
... (9 more like that)
],
"participantIdentities": [],
"teams": [
{
"teamId": 100,
"winner": false,
"firstBlood": true,
"firstTower": false,
"firstInhibitor": true,
"firstBaron": false,
"firstDragon": true,
"towerKills": 6,
"inhibitorKills": 2,
"baronKills": 0,
"dragonKills": 3,
"vilemawKills": 0,
"dominionVictoryScore": 0,
"bans": [
{
"championId": 120,
"pickTurn": 1
},
{
"championId": 37,
"pickTurn": 3
},
{
"championId": 13,
"pickTurn": 5
}
]
},
{
"teamId": 200,
"winner": true,
"firstBlood": false,
"firstTower": true,
"firstInhibitor": false,
"firstBaron": false,
"firstDragon": false,
"towerKills": 11,
"inhibitorKills": 4,
"baronKills": 0,
"dragonKills": 0,
"vilemawKills": 0,
"dominionVictoryScore": 0,
"bans": [
{
"championId": 28,
"pickTurn": 2
},
{
"championId": 38,
"pickTurn": 4
},
{
"championId": 63,
"pickTurn": 6
}
]
}
]
}
Expected output:
{
_id: { championId: Number, day: Number }
value: { banned: Number, firstBanned: Number }
}
After that, its supposed to merge with the results of a previous MapReduce operation, copying all the fields of documents with the same key (in the reduce function), but thats irrelevant now since the error happens before...

Mongoose model values being returned as a string instead of an object

I have a mongoose model that has some nested properties. When I query for a document using this model, the document is returned but I can only access the properties two levels deep, sometimes. Other nested objects are returned as something other than an object whose properties i can access with dot notation, I can't figure out why.
Does anyone know what may be causing this?
var mySchema = new Schema({
settings: {
some_settings: {
enabled: { type: Number, min: 0, max: 1, default: 0 },
interval: { type: Number, min: 0, default: 30 }, // seconds
start_diff: { type: Number, min: 0, default: 3600 } // seconds
},
other_settings: {
push_settings: { type: Number, min: 0, max: 1, default: 1, sparse: true }
}
}
});
When I get this returned after a findOne query and run settings.other_settings.push_settings, this returns undefined even though the value is in the database. But if I console.log(settings.other_settings) the console prints out the correct values, but they can't be accessed. It's as if mongoose isn't recognizing that this nested object exists.
EDIT: The document I receive after running findOne prints to the console like this:
{
_id: ObjectId('...'),
settings: {
some_settings: { enabled: 1, interval: 30, start_diff: 3600 },
other_settings: { push_settings: 1 }
}
}

Resources