Sequelize: Querying if ARRAY contains a value - postgresql

Suppose I have a PG ARRAY field:
id | array |
===|=============|
1|{"1","2","3"}|
How do I use sequelize to query to see if the array field as the value 1.
I tried:
array: { $contains: "1" }
which gives me:
array #> "1"
with error:
Possibly unhandled SequelizeDatabaseError: array value must start with "{" or dimension information
UPDATE
I was able to do it by:
array: { $contains: '{' + value + '}' }
Is there a more correct way?

I realised that sequelize is expecting the condition to be an array:
array: { [Op.contains]: ["1"] }
That will work. Cheers!!
Bear in mind that Op is exported from sequelize
const { Op } = require('sequelize');
or
import { Op } from 'sequelize';
See official docs: https://sequelize.org/master/manual/model-querying-basics.html#operators

Maybe so.
`{ genres: { $contains: [genreType] } }`
genres is an array. genreType can also be an array.
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: /* one of 'mysql' | 'mariadb' | 'postgres' | 'mssql' */,
operatorsAliases: Sequelize.Op.Aliases,
});

Related

Mongo Bulkwrite with $addToSet

I have been trying a bulkwrite but get complained about typing (I think it's about the syntax):
Type '{ roles: string; }' is not assignable to type 'SetFields<any>'.
Type '{ roles: string; }' is not assignable to type 'NotAcceptedFields<any, readonly any[]>'.
Property 'roles' is incompatible with index signature.
Type 'string' is not assignable to type 'never'.ts(2345)
I can't find any examples or docs about using $addToSet in a builkwrite. Here it is (INTER_ADMINS is just an array of string):
const bulkUpdates = INTER_ADMINS.map((ethAddress) => {
return {
updateOne: {
filter: { ethAddress },
update: {
$addToSet: {
roles: 'INTERNAL_ADMIN',
},
},
upsert: true,
},
};
});
const res = await db.collection('users').bulkWrite(bulkUpdates);
users collection sample:
{
ethAddress: 'something',
roles: ['role1','role2']
}
Appreciate your help
The syntax is correct, this is just a typescript error. I recommend you just add a #ts-ignore and move on.
Here is the type definition:
export type UpdateQuery<TSchema> = {
....
$addToSet?: SetFields<TSchema> | undefined;
....
};
export type SetFields<TSchema> = ({
readonly [key in KeysOfAType<TSchema, ReadonlyArray<any> | undefined>]?:
| UpdateOptionalId<Unpacked<TSchema[key]>>
| AddToSetOperators<Array<UpdateOptionalId<Unpacked<TSchema[key]>>>>;
} &
NotAcceptedFields<TSchema, ReadonlyArray<any> | undefined>) & {
readonly [key: string]: AddToSetOperators<any> | any;
};
As you can see because the Schema is not provided typescript doesn't know which are the valid "keys" of the schema so the only valid type left in the SetFields is the NotAcceptedFields fields type (which are null and undefined, not string )
If you provide a Schema to the operations I believe it should sort the issue:
const bulkUpdates: BulkWriteOperation<UserSchema>[] = ...

How do I get a string multiple values using the same key name that aren't in an array found in a mongodb database

mongodb is set up as so
_id:63457fde325244fe6b157dda
name:"Lisa"
number"248XXXXXXX"
sign:"scorpio"
createdAt:2022-10-11T14:38:22.991+00:00
updatedAt:2022-10-11T14:38:22.991+00:00
__v:0
_id:6345f0996e609ff4da70a6a9
name:"Alyssa"
number"248XXXXXXX"
sign:"vigo"
createdAt:2022-10-11T14:38:22.991+00:00
updatedAt:2022-10-11T14:38:22.991+00:00
__v:0
So I'm trying to pull all the values with the same key "sign" using mongodb.Basically all I've gotten so for is this..
function findSign() {
sun = ["aries", "taurus", "gemini", "cancer", "leo", "virgo", "libra", "scorpio", "sagittarius", "capricorn", "aquarius", "pisces"]
output= []
for(i=0; i<sun.length;i++){
User.find(
{sign:sun[i]},
(err, sign) => {
sign[i].push(output),
console.log(sign)
})
}
}
I want just an output to be a string of
virgo
scorpio
Try using the $in operator for filtering, distinct to return only a single sign per type, and select to return only the sign field:
function findSign() {
sun = [
'aries',
'taurus',
'gemini',
'cancer',
'leo',
'virgo',
'libra',
'scorpio',
'sagittarius',
'capricorn',
'aquarius',
'pisces',
];
User.find({ sign: { $in: sun } })
.distinct('sign')
.select('sign -_id')
.exec((err, res) => {
console.log(res);
});
}

How to make Mongoose model.insertMany insert documents with numerical and ordered ids?

I have this route in the backend express server:
router.route('/fillInformationAssetsSeverityEvaluation').post((req, res) => {
informationAssetsSeverityEvaluationRow.remove({}, (err) => {
if (err)
console.log(err);
else
// res.json("informationAssets Collection has been dropped!");
res.json('information Assets Severity Evaluation data has been received on the server side')
informationAssetsSeverityEvaluationRow.insertMany([req.body[0]], {
multi: true
}).then(documentsInserted => {
console.log('[req.body[0]]: ', [req.body[0]]);
console.log('documentsInserted: ', documentsInserted);
console.log('You have succesfully inserted ', documentsInserted.length, ' documents in informationAssetsSeverityEvaluation collection');
});
});
})
For the sake of simplicity, I am inserting only one document.
[req.body[0]]
{ REF: 'REFSHIT',
confFin: 'A',
confRep: 'A'}
But, in the real applications, I am inserting multiple documents similar to that.
This consoleLog :
console.log('documentsInserted: ', documentsInserted);
logs:
documentsInserted: [ { _id: 5d3453afc302d718e4870b53,
REF: 'REFSHIT',
confFin: 'A',
confRep: 'A'}]
As you see the id is automatically generated:
> _id: 5d3453afc302d718e4870b53
What I would like is: The ids of the different documents to be "numerically ordered". I.e:
Document 0 would have id 0
Document 1 would have id 1
Document 2 would have id 2
And so on and so forth.
After having made some research, I found out that I can do this manually by inserting the id manually inside the updateMany objects.
However, since I receive the documents objects from the request body, this is not a viable solution.
Any help?
Finally after trying four modules and a couple of days of trying for something that should be native to mongodb, I have found a simple solution. I hope it helps someone.
1/ Install mongoose-plugin-autoinc
2/
import mongoose from 'mongoose';
import { autoIncrement } from 'mongoose-plugin-autoinc';
const connection = mongoose.createConnection("mongodb://localhost/myDatabase");
const BookSchema = new mongoose.Schema({
author: { type: Schema.Types.ObjectId, ref: 'Author' },
title: String,
genre: String,
publishDate: Date
});
BookSchema.plugin(autoIncrement, 'Book');
const Book = connection.model('Book', BookSchema);
2/ In my case I have the models defined in models.js and the connection defined in server.js so I had to write this :
BookSchema.plugin(autoIncrement, 'Book');
in models.js
and instead of
const Book = connection.model('Book', BookSchema);
I have:
module.exports = {
informationAssetsRow: mongoose.model('informationAssetsRow', informationAssetsRow),
};
And in server.js:
const {
informationAssetsRow,
} = require('./models/models')

Unexpected <EOF> while using graphql

Getting EOF error every time at same line, changed code many times and even degraded to previous versions of graphql but no positive results.
My code is:
const graphql = require('graphql')
const _ = require('lodash')
const {
GraphQLObjectType,
GraphQLString,
GraphQLInt,
GraphQLSchema
} = graphql
const users = [
{id: '1', firstName: 'Ansh', age: 20},
{id: '2', firstName: 'Ram', age: 21},
{id: '3', firstName: 'Sham', age: 20}
]
const UserType = new GraphQLObjectType({
name: 'User',
fields: {
id: {type: GraphQLString},
firstName: {type: GraphQLString},
age: {type: GraphQLInt}
}
})
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: {
user: {
type: UserType,
args: {id: {type: GraphQLString}},
resolve(parentValue, args) {
return _.find(users, {id: args.id})
}
}
}
})
module.exports = new GraphQLSchema({
query: RootQuery
})
Error is:
{
"errors": [
{
"message": "Syntax Error GraphQL request (30:1) Unexpected <EOF>\n\n29: \n30: \n ^\n",
"locations": [
{
"line": 30,
"column": 1
}
]
}
]
}
The issue is because the query you're passing might be empty.
For example:
curl -X POST http://localhost:4000/graphql \
-H "Content-Type: application/json" \
-d '{"query": "{ user { id } }"}'
works fine.
But if you make something like:
curl -X POST http://localhost:4000/graphql \
-H "Content-Type: application/json" \
-d '{"query": ""}'
You'll get unexpected < EOF >
Also, check GraphQL end of line issue.
I had comments in the schema.graphql file:
"""
Some comments
"""
I removed the comments and the Unexpected <EOF> error went away.
It's because there's no actual query so you get unexpected EOF (End of File).
Guessing that you're using GraphiQL (because your EOF message says line 30); you need to add a query on the left-hand panel of GraphiQL in the browser. Something which conforms to your RootQuery like:
{
user(id: "1") {
id,
firstName,
age
}
}
I got this error while trying to stitch my schema
the reason for this error was that I delcared a type but didn't implemet it, had empty body, for example:
type User {
}
implementing the type fixed it
It looks like if we are doing the schema-first approach, but we do not have any .graphql files in your project/empty. I added this and the error went away:
src/example.graphql
type Query {
hello: String
}
The "GraphQLError: Syntax Error: Unexpected " error is coming from the graphql package. It looks like #nestjs/graphql is assuming that there will always be at least one .graphql file, so this is probably a bug to try and parse an empty schema vs display a more developer-friendly message or ignore it.
In most cases passing an empty query is caused to this error.
To avoid this try this in your graphiql
query {
user {
fields you need to retrieve
}
}
This is because your graphql.gql looks like this:
# ------------------------------------------------------
# THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
# ------------------------------------------------------
directive #key(fields: String!) on OBJECT | INTERFACE
directive #extends on OBJECT | INTERFACE
directive #external on OBJECT | FIELD_DEFINITION
directive #requires(fields: String!) on FIELD_DEFINITION
directive #provides(fields: String!) on FIELD_DEFINITION
One thing you can do is create a dummy resolver.
// src/graphql/resolvers/user.resolver.ts
import { Resolver, Query } from '#nestjs/graphql';
import { User } from 'models/User.model';
#Resolver(() => User)
export class UserResolver {
#Query(() => User)
async ids() {
return [];
}
}
and create a graphql model:
// src/graphql/models
import { Field, ObjectType } from '#nestjs/graphql';
#ObjectType()
export class User {
#Field()
createdAt: Date;
}
And make sure that resolver is imported by a module and the module is added to App.module
This should fix it!
In my case on the frontend side (Angular), since I just wanted to observe something, I have this code:
I got this error:
Error: Unexpected <EOF>.
and I made it comment-line and the error was gone
How to fix it: Go to node_mudules > graphql > syntaxError.js and delete all comments from this file and the error should be gone.

StrongLoop query/stored procedure with Postgres?

Per the docs, StrongLoop doesn't support running custom sql statements.
https://docs.strongloop.com/display/public/LB/Executing+native+SQL
How anyone thinks you can build an enterprise app with just simple joins is beyond me, but I did find this post which says you can do it:
Execute raw query on MySQL Loopback Connector
But this is for MySql. When I try it with Postgres I get the error: "Invalid value for argument 'byId' of type 'object': 0. Received type was converted to number." And it returns no data. Here is my code:
module.exports = function(account) {
account.byId = function(byId, cb){
var ds=account.dataSource;
var sql = "SELECT * FROM account where id > ?";
ds.connector.execute(sql, [Number(byId)], function(err, accounts) {
if (err) console.error(err);
console.info(accounts);
cb(err, accounts);
});
};
account.remoteMethod(
'byId',
{
http: {verb: 'get'},
description: "Get accounts greater than id",
accepts: {arg: 'byId', type: 'integer'},
returns: {arg: 'data', type: ['account'], root: true}
}
);
};
For the part [Number(byId)], I've also tried [byId] and just byId. Nothing works.
Any ideas? So far I really like StrongLoop, but it looks like the Postgresql connector is not ready for production. I'll be doing a prototype with Sails next if this doesn't work. :-(
Here's the thing arg is of type 'integer' which is not a valid Loopback Type. Use `Number instead. Check the corrected code below:
module.exports = function(account) {
account.byId = function(byId, cb){
var ds = account.dataSource;
var sql = "SELECT * FROM account WHERE id > $1";
ds.connector.execute(sql, byId, function(err, accounts) {
if (err) console.error(err);
console.info(accounts);
cb(err, accounts);
});
};
account.remoteMethod(
'byId',
{
http: {verb: 'get'},
description: "Get accounts greater than id",
accepts: {arg: 'byId', type: 'Number'},
returns: {arg: 'data', type: ['account'], root: true} //here 'account' will be treated as 'Object'.
}
);
};
Note: MySQL's prepared statements natively use ? as the parameter placeholder, but PostgreSQL uses $1, $2 etc.
Hope this works for you. Else try with [byId] instead of byId as per the docs.