Using root object in graphql resolver function to access parent fields properties - javascript

I am using neo4j-graphql-js library to auto generate resolvers from the schema. For a node in the schema(Employee) i need to get a particular node property(empid) from a rest call as we plan to remove that property from our neo4j database due to privacy issues. I am trying to write a custom resolver for that field . I have added #neo4j directive to that field in the schema for neo4j to ignore it. I need to make a rest call that accepts a parameter named uid and returns the corressponding empid. This iuid is a property of Employee node and so is present in my neo4j DB.
The issue is while writing the resolver the root objects only holds the filed values accesed in the query. So if iuid is not part of the query i'm unable to get it's value in the root obj.
Here is my employee node: -
type Employee{
empId: String #neo4j_ignore
buCode: String
iuid: String
name: String
projectCode: String
roleCode: String
grade: String
mailid: String
duCode: String
txtmailid_new: String
Here is my resolver where for my i am returning a dummy string instead of making a rest call: -
const resolvers={
Employee: {
empId: async (obj, params, ctx, resolveInfo) => {
console.log(obj.iuid);
var result="dummy_emp_id";
return result;
}
}
};
const schema = makeAugmentedSchema({ typeDefs, resolvers} );
const server = new ApolloServer({ schema, context: { driver } });
server.listen(3003, '127.0.0.1').then(({ url }) => {
console.log(`GraphQL API ready at ${url}`);
});
Here is my query:-
{
Employee(first : 10)
{
empId
name
}
}
I want to access all the value of all the field of the employee node so i can get the iuid.The console log returns undefined as the root object only has the queried field. I don't know even if it is possible and if not is there any workaround this?

Related

GitHub GraphQL API query for response simplification [duplicate]

Let's say I've got a GraphQL query that looks like this:
query {
Todo {
label
is_completed
id
}
}
But the client that consumes the data from this query needs a data structure that's a bit different- e.g. a TypeScript interface like:
interface Todo {
title: string // "title" is just a different name for "label"
data: {
is_completed: boolean
id: number
}
}
It's easy enough to just use an alias to return label as title. But is there any way to make it return both is_completed and id under an alias called data?
There is no way to do that. Either change the schema to reflect the client's needs or transform the response after it is fetched on the client side.

TypeORM findby Child Properties of a MongoDB Document

I have a MongoDB document in the following format. I can verify that it exists in MongoDB using Compass. I'm using TypeORM to make the query, not MondoDB.
{
_id: 'some id'
user: {
details: {
email: "test#test.ch",
username: "testname"
},
status: 'active'
}
}
Is it possible to use TypeORM to find by, say, the email?
I've tried
const emailExists = await this.userRepo.findOneBy({
user: {
details: {
email: "test#test.ch"
}
}
});
but emailExists always returns null even though I can validate that it exists in MongoDB. I've tried other ways to find by email using find, findOne, and more.
How do you find a matching value of a child property, like email? Is there a better approach?
MongoDB: Query on Nested Field
To specify a query condition on fields in an embedded/nested document, use dot notation.
Example: 'field.nestedField'
When querying using dot notation:
The field and nested field must be inside quotation marks.
Applying in your code:
const emailExists = await this.userRepo.findOneBy({'user.details.email': 'test#test.ch'});
Reference:
MongoDB Official Documentation: Query on Embedded/Nested Documents
Update: Looks TypeORM not work well with MongoDB, but you can try use $match.
Example:
$match : { 'field.nestedField': nestedField }
Applying in your code:
this.userRepo.findOneBy({$match: { 'user.details.email': 'test#test.ch' }});
If not work maybe try to change TypeORM to Mongoose.
Reference:
https://github.com/typeorm/typeorm/issues/2483

perform a TypeOrm find search operation for matching array of json

i have my typeorm column like this, what i want is an array of JSON object which i manage to get.
#Column({
type: 'jsonb',
array: false,
default: () => "'[]'",
nullable: false,
})
tokens!: Array<{ token: string }>;
this is how the field looks, and am fine with it, what i want is to find a document with a particular token, so i came up with the below code, but it returns an empty array.
const user = await User.find({ where: { _id: decoded._id, tokens: { token: token } } });
normally when am using mongooe i can get this working using
const user = await User.findOneBy({_id: decoded._id, "tokens.token": token,}); and this returns a particular user, with the id and token string passed.
i want help on how to find a user using the id and the token string inside in array of object, thanks.
TypeORM does not natively support queries on PostreSQL jsonb columns. Performing a query on the data in a jsonb column would require you to either issue a raw query or write your own WHERE clause in.where or .addWhere of a query builder (doc).
For reference, the jsonb query syntax documentation can be found here.

In a Nodejs Sequelize model, how to obtain type information of attributes?

I have a working model with Postgres and sequelize in NodeJS. Say the model is Person and has name and age fields. Now I want to dynamically inspect the model class and obtain information about it's attributes, like their name and most of all type.
Using Person.attributes
I get some information:
name:
{ type:
{ options: [Object],
_binary: undefined,
_length: 255 },
But as you can see the type object does not inform about name being a varchar or boolean.
Does anyone know, how to get this information with sequelize
You can iterate over rawAtributes of Model
for( let key in Model.rawAttributes ){
console.log('Field: ', key); // this is name of the field
console.log('Type: ', Model.rawAttributes[key].type.key); // Sequelize type of field
}
So the example for name being a Sequelize.STRING would be
Field: name
Type: STRING
Or you can do almost the same iteration but instead using Model.rawAttributes[key].type.key you can use Model.rawAttributes[key].type.toSql(), which would generate this result
Field: name
Type: VARCHAR(255)
EDIT
Accessing defaultValue of field:
Model.rawAttributes[field].defaultValue
Checking if field allows NULL values:
Model.rawAttributes[field].allowNull
You are looking for native type information, it seems.
I'm not familiar with Sequelize, except I know it uses node-postgres driver underneath, which automatically provides the type information with every query that you make.
Below is a simple example of dynamically getting type details for any_table, using pg-promise:
var pgp = require('pg-promise')(/*initialization options*/);
var db = pgp(/*connection details*/);
db.result('SELECT * FROM any_table LIMIT 0', [], a => a.fields)
.then(fields => {
// complete details for each column
})
.catch(error => {
// an error occurred
});
There are several fields available for each column there, including name and dataTypeID that you are looking for ;)
As an update, following the answer that does use Sequelize for it...
The difference is that here we get direct raw values as they are provided by PostgreSQL, so dataTypeID is raw type Id exactly as PostgreSQL supports it, while TYPE: STRING is an interpreted type as implemented by Sequelize. Also, we are getting the type details dynamically here, versus statically in that Sequelize example.
item.rawAttributes[key].type.key === this.DataTypes.JSONB.key;
#piotrbienias Is above comparison valid ?
(Sorry for writing here as I can't add comments)

MarkLogic: find by property value

I have a MarkLogic 8 database:
declareUpdate();
var book0 = {
id: fn.generateId({qwe: 'book'}),
username: 'book',
password: 'pass'
};
var book1 = {
id: fn.generateId({asd: 'book'}),
username: 'user',
password: 'pass1'
};
xdmp.documentInsert(
'zz' + book0.id,
book0,
xdmp.defaultPermissions(),
['qwe']);
xdmp.documentInsert(
'xx' + book1.id,
book1,
xdmp.defaultPermissions(),
['qwe']);
So I want to find them by name with the Node.js API:
var db = marklogic.createDatabaseClient(connection.connInfo);
var qb = marklogic.queryBuilder;
function findByName(name) {
return db.documents.query(
qb.where(
qb.collection('qwe'),
qb.value('username', name)
)
).result();
}
The problem is that it finds not only user or user0, but also users and if I create a document with username book it will find both book and books.
A values query matches the entire text of a JSON property by stemming each word in the text (if stemming is enabled, which is the default).
Where (as in this case) that's not what you want, you can do either of the following:
Create a string range index (with the root collation if you only need exact matches) for the JSON property
Turn on word searches in the database configuration and use the "unstemmed" option on the query.
If you also turn off stemmed search in the database configuration, you don't have to pass the option (and avoid the extra resource required for both types of indexes).
To limit the configuration change to a specific property, you can configure a field for the property instead of configuring the entire database.
For more background, see:
http://docs.marklogic.com/guide/search-dev/stemming
http://docs.marklogic.com/guide/admin/text_index
http://docs.marklogic.com/cts.jsonPropertyValueQuery?q=cts.jsonPropertyValueQuery&v=8.0&api=true
Hoping that helps,

Categories

Resources