Cassandra support in apollo graphql - node.js

I want to connect Apache Cassandra to apollo graphql server. Is there any ORM library available for cassandra in node just like Sequelize for relational databases.
Can any one please help me out

Maybe this could help:
http://express-cassandra.readthedocs.io/en/stable/
From the description of the page: Express-Cassandra is a Cassandra ORM/ODM/OGM for NodeJS with Elassandra & JanusGraph Support.

There is an automatically generated GraphQL API for Cassandra that you can run as a service to expose your CQL tables via GraphQL.
GitHub repo: https://github.com/datastax/cassandra-data-apis
Small Example:
Say you have the a table called books
CREATE TABLE library.books (
title text PRIMARY KEY,
author text
);
It will automatically generate these APIs
schema {
query: Query
mutation: Mutation
}
type Query {
books(value: BooksInput, orderBy: [BooksOrder], options: QueryOptions): BooksResult
booksFilter(filter: BooksFilterInput!, orderBy: [BooksOrder], options: QueryOptions): BooksResult
}
type Mutation {
insertBooks(value: BooksInput!, ifNotExists: Boolean, options: UpdateOptions): BooksMutationResult
updateBooks(value: BooksInput!, ifExists: Boolean, ifCondition: BooksFilterInput, options: UpdateOptions): BooksMutationResult
deleteBooks(value: BooksInput!, ifExists: Boolean, ifCondition: BooksFilterInput, options: UpdateOptions): BooksMutationResult
}
And you can query them with
mutation {
catch22: insertBooks(value: {title:"Catch-22", author:"Joseph Heller"}) {
value {
title
}
}
}
query {
books (value: {title:"Catch-22"}) {
values {
title
author
}
}
}

Related

Moleculer sequlize get tables data by joins

I am using moleculer micro services and postgres database with modules moleculer-db-adapter-sequelize and Sequelize. Every service have one table model. For e.g. user.service.js has user table model, application.service.js has application table model. I want to get data from both tables using join. I tried with join query but it returns
Relation does not exist
How to make joins of two models in moleculer architecture?
moleculer-db works as one-service-one-table concept. You should write your custom DB service to implement multiple models & joins.
In Moleculer level, the populate can be used to join data between services.
Populate example:
settings: {
fields: ["_id", "author", "article", "body", "createdAt", "updatedAt"],
populates: {
"author": {
action: "users.get",
params: {
fields: ["_id", "username", "bio", "image"]
}
}
}
},

ValidationException: The table does not have the specified index: GameTitleIndex

I am using Vogels, DynamoDB data mapper for NodeJS. I am querying against a global index according to the Vogels' documentation. All I have done is, created a model with a global secondary index like this:
let MyModel = vogels.define('MyModel', {
hashKey: 'uuid',
timestamps: true,
updatedAt: 'updated_at',
createdAt: 'created_at',
schema: MyModelBaseSchema,
indexes : [{
hashKey : 'gameTitle', rangeKey : 'topScore', name : 'GameTitleIndex', type : 'global'
}]
});
and querying against this index
MyModel.query('game 1')
.usingIndex('GameTitleIndex')
.loadAll()
.select("COUNT");
When running any tests it shows an exception ValidationException: The table does not have the specified index: GameTitleIndex
According to the documentation, this is all I have to do to get data. Is there anything which I have missed to query this index?
Any answers will be appreciated.
Thanks in advance.
– In case you are using Serverless framework with serverless-dynamodb-local and serverless-offline plugins (for local testing).
– And in case you are created new Local Secondary Index, but the command shown below still not showing it under LocalSecondaryIndexes configuration node:
aws dynamodb describe-table --table-name YOUT_TABLE_NAME --endpoint-url http://localhost:8000
– And in case you are receiving error ValidationException: The table does not have the specified index: YOUR_INDEX_NAME when using code similar to shown below:
query(uid, id) {
const params = {
TableName: YOUR_TABLE_NAME,
IndexName: YOUR_LSI_NAME,
KeyConditionExpression: "#uid = :uid and #id = :id",
ExpressionAttributeNames: {
"#uid": "uid",
"#id": "id",
},
ExpressionAttributeValues: { ":uid": uid, ":id": id },
};
return DB.query(params).promise();
}
Then most likely you need to delete local DynamoDB database file and restart services with serverless offline start command. This will force recreation of local DynamoDB database file with proper Local Secondary Indexes.
To delete local DynamoDB database file do the following:
Update the serverless.yml by specifying path to DynamoDB database, like shown below:
custom:
dynamodb:
stages:
- ${self:provider.stage}
start:
port: 8000
inMemory: true
migrate: true
dbPath: "./.db" # Make sure that folder exists!
Now you can go to the folder ./.db and remove file shared-local-instance.db (which is a SQLite database which mimics DynamoDB :0).
As result on next start with the command serverless offline start the up to date local DynamoDB database file will be created.
In case someone's stuck at the same issue, here is the answer:
After creating a new index in model, either local secondary index or global secondary index, Migrations are to be run. Only after then the table will have the specified index. Refer to this issue for more clarification.

executing direct query in controller in loopback

I have started working in loopback 4.I have created a default CRUD controller with basic CRUD operations which can get 'the table data', 'the table record for particular id' etc.. what I need now is I want to execute my own query for this table. How to write a query in controller and execute it?
/* below is the default function to get table data*/
#get('/customers', {
responses: {
'200': {
description: 'Array of customers model instances',
content: {
'application/json': {
schema: {type: 'array', items: {'x-ts-type': Customers}},
},
},
},
},
})
async find(
#param.query.object('filter', getFilterSchemaFor(Customers)) filter?: Filter,
: Promise<Customers[]> {
if (limit > 100) limit = 100; // your logic
return await this.CustomersRepository.find(filter);
}
the type of code I want is,
Execute(dataset, sqlstatement); //is that available?
Support for executing raw database queries was added recently by the pull request #2681, this functionality is provided by Repository method execute.
Please note that they query format is connector-specific. For example, if you are using MySQL database, then you can write the following query:
await this.CustomersRepository.execute(
// the query template, use "?" for variables to AVOID SQL INJECTIONS ATTACKS!
'SELECT TOP ? * FROM CUSTOMERS',
// the values to use for variables
[limit]);

Leveraging both GraphQL and Mongoose

Is it possible to leverage both GraphQL and Mongoose?
So far, I have been able to integrate both GraphQL and Mongoose to handle populating the database, but I am struggling to understand how this can work to retrieve data, specifically data with nested references.
Consider this schema:
const fooSchema = new Schema({
name: { type: 'String', required: true },
bar: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'Bar',
required: false,
}],
});
The Bar schema is essentially the same, with just a field for "name".
Is it possible to run a GraphQL query to populate the data with the references in 'bar'?
Currently, we are using GraphQL-Tools to create our typeDefs, Mutations, and Queries which looks something like this:
const typeDefs = `
type Foo {
name: String!,
bars:[Bar]
}
type Bar {
_id: ID,
name: String,
}
type Query {
allFoos: [Foo!]!
foo(_id: ID!): Foo
}
type Mutation {
...
}
`;
module.exports = makeExecutableSchema({typeDefs, resolvers});
And finally a query directive that looks like this:
const allFoos = async (root, data) => {
return await Foo.find({});
};
I am able to change the query directive to use .populate() to get Bar, but that does not actually end up populating the results, which I think is because of the way the typeDefs are set up.
So is it possible to make these two concepts work together? Does it even make sense to use them both?
As they describe GraphQL:
GraphQL is a query language for your API, and a server-side runtime
for executing queries by using a type system you define for your data.
GraphQL isn't tied to any specific database or storage engine and is
instead backed by your existing code and data.
Where as mongoose is
Writing MongoDB validation, casting and business logic boilerplate is
a drag. That's why we wrote Mongoose
Monogoose work with mongodb validation whereas graphql is a query language for the API.
You can read a basic example from here about Setting up a simple GraphQL Server with Node, Express and Mongoose.
These two are completely different. Mongoose work when you are performing any operation on database, whereas grapgl comes in picture when you call a API. Graphql validate your API input parameter and return parameter. If you are adding these two in single app. It will work well.
Mongoose will validate your db operation.
GraphQL will validate your API input and output parameter.

How to create a UNIQUE constraint on a JSONB field with Sequelize

I'm using the Sequelize ORM in NodeJS to manage a postgreSQL database.
I'm using the JSONB datatype in my table, I need an index on the JSONB field and an unique constraint on a property of this JSON.
If I have to do in a classic SQL here my script :
CREATE TABLE tableJson (id SERIAL PRIMARY KEY,
content JSONB NOT NULL);
CREATE INDEX j_idx ON tableJson USING gin(content jsonb_path_ops);
CREATE UNIQUE INDEX content_name_idx ON tableJson(((content->>'name')::varchar));
I've found how to create the table with the INDEX but not how to deal with the UNIQUE constraint. Here is a sample of my script :
var tableJson = sequelize.define('tableJson', {
content: Sequelize.JSONB
}, {
indexes: [{
fields: ['content'],
using: 'gin',
operator: 'jsonb_path_ops'
}
});
Is there a solution for my problem? If not I'll probably use the sequelize.query method to execute raw query but this is not very evolutive.
Any help would be appreciated!
This is the workaround I use to add indexes on JSONB fields with Postgres and Sequelize.
First, set the quoteIdentifiers option to false in your Sequelize client.
const seq = new Sequelize(db, user, pass, {
host: host,
dialect: 'postgres',
quoteIdentifiers: false,
});
(Watch out though, this will make all your table names case insensitive when created by Sequelize.sync())
You can now add indexes on JSONB fields this way in your model definition :
indexes: [
{
fields: ['content'],
using: 'gin',
operator: 'jsonb_path_ops'
},
{
fields: ['((content->>\'name\')::varchar)'],
unique: true,
name: 'content_name_idx',
}
],

Resources