I am trying to pass a graph ql arguments array in cypher query. I am having difficulty making query work. I can see the parameter passed correctly while doing console log. However, when I try to utilize with node js. Neo4j driver is not doing anything. I think I am doing something wrong. Could anyone please guide me.
using neo4j 3.5.12
const query = `UNWIND $list as batch
match ((u:user { ohrid: ${ctx.ohrid}})-[:FILE_SHARED_WITH| FILE_SHARED_WITH_GROUP| MEMBER_OF_GROUP*..2]-(f:file)) where f.uuid = batch.uuid
SET f.documentStatus = batch.documentStatus
return f as files`;
const queryParams = { list: args.documents }; // args.document is arguments from gql mutation
const result = await session.run(query, queryParams);
if I use the same query in neo4j browser it works fine
UNWIND [{id: 2, documentStatus: "unpublished"}, { id: 32, documentStatus: "unpublished"}] as batch
match ((u:user { ohrid: 850046714})-[:FILE_SHARED_WITH| FILE_SHARED_WITH_GROUP| MEMBER_OF_GROUP*..2]-(f:file)) where ID(f) = batch.id and any(x in batch.documentStatus where x in ['published', 'unpublished'])
SET f.documentStatus = batch.documentStatus
return f
Cheers
~ Meet
Related
I have this really simple querybuilder in TypeOrm, working on a NodeJs with typescript backend and a MariaDB database
const queryBuilder = this.createQueryBuilder('cities')
return queryBuilder.where('cities.id = :q', { q }).take(limit).skip(offset).getMany()
and it is not passing the q parameter right, it outputs the following:
query: SELECT `cities`.`id` AS `cities_id`, `cities`.`state_id`
AS `cities_state_id`, `cities`.`name` AS `cities_name`, `cities`.`created_at` AS `cities_created_at`, `cities`.`updated_at`
AS `cities_updated_at` FROM `cities` `cities`
WHERE `cities`.`id` = ? LIMIT 8 -- PARAMETERS: ["2"]
I already tried passing just the q variable, it says that i have to pass an object literal so i pass the q parameter inside an object, i tried using the set parameter method as follows
return queryBuilder
.where('cities.id = :q', { q })
.setParameter('q', q)
.take(limit)
.skip(offset)
.getMany()
and its giving me the same output.
I want to create a simple REST endpoint with OData and the $filter parameter.
This is my filter query param: $filter=shoecolor eq 'black'
And this is my node js code:
import { createFilter } from "odata-v4-pg";
...
var filter = createFilter(req.query.$filter + "");
const projectName = req.params.projectname;
const storeName = req.params.storename;
this.logger.info(filter.where); // prints: "shoecolor" = $1
var result = await this.database.any(`SELECT * FROM $1:name.$2:name WHERE ${filter.where}`, [projectName, storeName]);
this.logger.info(result); // prints an empty array!!!
...
Why is my SELECT with OData $filter always empty?
I found the solution on my own: I forgot to pass filter.parameters to the query. This link gives a good example: https://www.npmjs.com/package/odata-v4-pg?activeTab=readme
I don't get this. I have a service that injects entity repositories and has dedicated methods to do some business logic and functions.
Beside that I expose a method that just returns QueryBuilder - to avoid injecting repositories all over the place - for a few occasions when other service needs just a quick query:
type EntityFields = keyof MyEntity;
entityQueryBuilder(alias?: string, id?: number, ...select: EntityFields[]) {
const q = this.entityRepository.createQueryBuilder(alias);
if (id) {
q.where({id});
}
if (select) {
q.select(select);
}
return q;
}
Now when I am trying to use this and call:
const r = await service.entityQueryBuilder('a', 1, 'settings').getOne();
the result is always empty although in the log the generated SQL is correct.
However when I do:
const r = await service.entityQueryBuilder('a', 1, 'settings').execute();
I get (almost) what I need. I get array instead of an entity object directly but the data are there.
I am unhappy though as I need to map the result to the object I wanted, which is something that getOne() should do on my behalf. getMany() does not return results either.
What did I do wrong?
Edit:
FWIW here is the final solution I came up with based on the hint in accepted reply:
entityQueryBuilder(id?: number, ...select: EntityFields[]) {
const q = this.entityRepository.createQueryBuilder('alias');
if (id) {
q.where({id});
}
if (select) {
q.select(select.map(f => `alias.${f}`));
}
return q;
}
Admittedly it has hardcoded alias but that I can live with and is OK for my purpose.
Hope this helps someone in the future.
It happens because you put no really proper select. In your case, you need a.settings instead of settings:
const r = await service.entityQueryBuilder('a', 1, 'a.settings').getOne(); // it should works
I'm trying to return a specific node with the id (using neo4j-driver package within my nodejs server). I have the id of the node I'm searching for. So I used the parameters in the run method as showed bellow but I'm not getting any nodes.
session.run('MATCH (n:User)-[:OWN]->(a) WHERE id(n) = $id RETURN a',{id: idUser})
I checked and idUser-value is 128 and when i'm running this command, I get the right node.
session.run('MATCH (n:User)-[:OWN]->(a) WHERE id(n) = 128 RETURN a',{id: idUser})
Is there any one to make the first command working so I can get the node of the given id ?
Thanks
As it is written in the driver documentation:
Number written directly e.g. session.run("CREATE (n:Node {age:
{age}})", {age: 22}) will be of type Float in Neo4j. To write the age
as an integer the neo4j.int method should be used...
https://github.com/neo4j/neo4j-javascript-driver#write-integers
So when you pass the identifier from the node.js, you need to convert it:
session
.run('MATCH (n:User)-[:OWN]->(a) WHERE id(n) = $id RETURN a', {
id: neo4j.int(idUser)
})
or:
session
.run('MATCH (n:User)-[:OWN]->(a) WHERE id(n) = toInteger($id) RETURN a', {
id: idUser
})
For an application I'm running a query on DocumentDb in .NET. For this used I wanted to use a parametrized query, like this:
var sqlString = "select p.Id, p.ActionType, p.Type, p.Region, a.TimeStamp, a.Action from History p join a in p.Actions where a.TimeStamp >= #StartTime and a.TimeStamp <= #EndTime and p.ClientId = #ClientId and p.ActionType = #ActionType";
if (actionType != "") { sqlString += actionTypeFilter; }
var queryObject = new SqlQuerySpec
{
QueryText = sqlString,
Parameters = new SqlParameterCollection()
{
new SqlParameter("#StartTime", startDate),
new SqlParameter("#EndTime", endDate),
new SqlParameter("#ClientId", clientId.ToString()),
new SqlParameter("#ActionType", actionType)
},
};
var dataListing = _documentDbClient.CreateDocumentQuery<PnrTransaction>(UriToPnrHistories, queryObject, new FeedOptions() { MaxItemCount = 1 });
When I execute this, I'm getting en empty dataset. But when I use the same query, and build it using classic string replace it works just fine.
Can anyone tell me what I'm doing wrong in my parametrized query?
If the code above is the running code, you still add the actiontypeFilter on the parameterized SQL string. Try to remove the if statement on line 2. Seems to me that may be your problem.
It would help if you could post a sample document from the server.
I usually see this syntax:
SqlParameterCollection parameters = new SqlParameterCollection();
parameters.Add(...);
parameters.Add(...);
Try that and see if you get different results. It might be that the list you use to initialize it in your answer needs to be typed differently to work.