Cypher Http request with match parameters - rest

I'd like to execute an http cypher query with parameters like :
{"statements":
[
{"statement":"MATCH path=(p:Person {props})-[*..100]->() RETURN [n in nodes(path)]",
"parameters":{"props":{"name":"Lucille"}}
}
]
}
However i get the following error Parameter maps cannot be used in MATCH patterns (use a literal map instead, eg. \"{id: {param}.id}\").
I have no idea how to use a literal map here.
Thanks for your help !

You can either have:
{
"statements": [{
"statement": "MATCH path=(p:Person { name: {name} })-[*..100]->() ...",
"parameters": { "name": "Lucille" }
}]
}
or MATCH path=(p:Person { name: props.{name} }) ... while keeping you initial parameters
The reason is given in this comment:
"Unlike properties in CREATE, MATCH requires the map to be a literal. This is because the property names must be known in advance, when the query is compiled, in order to efficiently plan its execution."

I think your query would become:
MATCH path=(p:Person {id: {props}.id })-[*..100]->()
RETURN [n in nodes(path)]

Related

Strapi API Rest V 3.6.8 how to search posts by title?

I have installed version 3.6.8 of Strapi
In the docs for v3.x
https://strapi.gitee.io/documentation/v3.x/content-api/parameters.html#filter
Filters are used as a suffix of a field name:
No suffix or eq: Equals
ne: Not equals
lt: Less than
gt: Greater than
lte: Less than or equal to
gte: Greater than or equal to
in: Included in an array of values
nin: Isn't included in an array of values
contains: Contains
ncontains: Doesn't contain
containss: Contains case sensitive
ncontainss: Doesn't contain case sensitive
null: Is null/Is not null
And I can see those examples
GET /restaurants?_where[price_gte]=3
GET /restaurants?id_in=3&id_in=6&id_in=8
etc..
So I tried
/posts?_where[title_contains]=foo
/posts?title_contains=foo
And I also tried the "new way" in V4
/posts?filters[title][contains]=foo
But all of this attempts return all the post, exactly the same than just doing
/posts?
Any idea how to filter by post title and/or post body?
Almost there my friend! The issue you are facing called deep filtering (please follow the link for documentation).
In Short: the title field is located inside the attributes object for each item
Your items may look something similar to this:
{
"data": [
{
"id": 1,
"attributes": {
"title": "Restaurant A",
"description": "Restaurant A's description"
},
"meta": {
"availableLocales": []
}
},
{
"id": 2,
"attributes": {
"title": "Restaurant B",
"description": "Restaurant B's description"
},
"meta": {
"availableLocales": []
}
},
]
}
And therefor the filter should be
/api/posts?filters[attributes][title][$contains]=Restaurant
Also note:
the $ sign that should be included for your operator (in our case contains)
the api prefix you should use before the plural api id (e.g. posts, users, etc.)
you may prefer using $containsi operator in order to ignore upper and lower case letters (better for searching operations)
Let me know if it worked for you!

Custom filters that accept objects - lighthouse-php

I am using lighthouse-php as Api Gateway in a micro services architecture.
So for all my types I make a request internally through Guzzle.
But I am needing to implement filters that are suitable for any type and that give flexibility when making queries.
I need to implement a query like this:
query news (
order_by: {publication_date: desc}
where: {
_or: {categories_id: { _eq: 1 }, title: { _ilike: "news" } }
}
limit: 10
offset: 20
) {
id
category_name: name
photo
publication_date
text
title
}
But I have no idea how to implement this "where" filter that receives a composite object as in this example.
Remember that this query will not use any model within lumen, since it will be a custom query that will make a request to the microservice of news.
What I need is the way that my query receives whatever comes in where, limit and order, to send it on request. But I have no idea how to build something like this in the scheme.
Anyone have any idea how to do it?
Thanks friends.
Yes, you can.
Just now I'm making an component that will receive criterias to filter in graphql query so I need to fill filter's where params with those criterias.
Imagine the following schema:
type News{
id: ID!
title: String!
views: Int!
}
type Query{
getNews(where: _ #whereConditions(columns:["title", "views"])) : [News!] #all
}
We can make a query and fill where variables later
query GetNews($whereNews: [GetNewsWhereWhereConditions!]){
getNews(where: {OR: $whereNews}){
title
views
}
}
When querying we can fill the variables sending an object like
{
"where":[
{"column": "TITLE", "operator": "LIKE", "value": "Amazing title"},
{"column": "VIEWS", "operator": "GTE", "value": 10,
]
}

Addition whithin Parameters Transactional Cypher

Here is my problem: I want to add a integer to a property (which is of course a number) of a relationship, using Transactional Cypher.
With SET, I manage to change the property as a parameter ; but I can not add a integer to this value.
When I wrote :
:POST /db/data/transaction/commit {
"statements": [
{
"statement": "MATCH (r:CONCEPT { EX : {Example}})-[proximity:FLIGHT]->(s:NARRATION {CARD_EX: {Example2}}) SET proximity = {prop} ;",
"parameters": {"Example":"Example","Example2":"Example2","prop":{"PROX": +144}}
}]
}
I obtain :
Payload does not seem to be valid (JSON) data
How can I add whithin Parameters ?
Thanks in advance.
Alex
The "+" sign in +144 is not legal in JSON. Also, that SET syntax does not support your desired functionality.
One workaround would be to just hardcode a portion of the SET clause:
:POST /db/data/transaction/commit {
"statements": [{
"statement": "MATCH (r:CONCEPT {EX:{Example}})-[proximity:FLIGHT]->(s:NARRATION {CARD_EX: {Example2}}) SET proximity.PROX = proximity.PROX + {val};",
"parameters": {"Example":"Example","Example2":"Example2","val": 144}
}]
}

OrientDB - Returning JSON with embedded vertices from a match query

I have issues returning a nice json with embedded vertices from the database.
Here is an example graph:
Here is an example query:
match {class: user, as: user, where: (name='tihomir')}
.both('hasA'){as: task}.both('hasA'){as: tag}
RETURN user, task.name, tag.name
The result is the expected one:
But what I really need is something like this:
[
{
user: {
name: "user_name",
tasks: [{
name: "task_name",
tags: [{
name: "tag_name"
}]
}]
}
}
]
I couldn't achieve this with the fetch API.
Did you try with "nested projections"?
The following should do the job:
match
{class: user, as: user, where: (name='tihomir')}
.both('hasA'){as: task}.both('hasA'){as: tag}
RETURN user:{*, tasks:{*, tags:{*}}}
Full docs here:
https://orientdb.com/docs/3.0.x/sql/SQL-Projections.html#nested-projections
#thinklinux you need version 3.0 or higher (not suitable for production) to do this the way Luigi Dell'Aquila does this.

Can I parameterize labels and properties on CREATE or SET? (REST and transaction)

I have a query
1. CREATE (a:%1$s {props}), (b:%2$s {props2}), (b)-[:%3$s {relProps}]->(a)
2. MATCH (a:%1$s { value:{value} })-[:%2$s]->(b) WHERE (b:%3$s) SET (b {props})
I'm using underscore.string to allow string format but would love to just stick with parameters.
Is it possible to parameterize labels such as
{
"query": CREATE (a:{label} {props}),
"params": {
"label":"SomeLabel",
"props":{....}
}
}
and is it also possible to parameterize properties on a SET?
{
"query": "MATCH ..... SET (node {props})"
"params": {
"props":{
"prop1:":"Property Name",
....
}
}
}
Also is there a way to parameterize on a "MERGE"? it gives me 'Parameter maps cannot be used in MERGE patterns (use a literal map instead, eg. "{id: {param}.id}")'
EDIT: what about parameterizing where clause?
MATCH (:Identity%1$s {nodeId:{nodeId})-[r*2..3]-(node1)-[b:%2$s]->(node2) %4$s return *
I have %4$s there for me to put whatever clauses I need to. If I want to have it as
WHERE node1.nodeId= {someNodeId} SET b= {props}
is that possible??
Also when I'm doing a transaction SET node={props} does not seem to work. I tried
statements:[
{
"statement":"..... SET node={props}",
"parameters":{
"props": {
"description":"some description"
}
}
}
]
Any suggestions?? Thank you!
You cannot parameterize labels since the query plan might look different for a different label.
Parameterizing multiple properties using a map is possible, note the slight difference in the SET syntax:
{
"query": "MATCH ..... SET node = {props}"
"params": {
"props":{
"prop1:":"Property Name",
....
}
}
}
Not 100% about MERGE but I guess this should work:
{
"query": "MERGE (n:Label {identifier: {idValue}) ON CREATE SET n = {props}"
"params": {
"identifier": 123,
"props":{
"identifier": 123,
"prop1:":"Property Name",
....
}
}
}
I found out!
CREATE ... SET node = {props}
does the trick to set multiple properties with parameters
doc: http://docs.neo4j.org/chunked/snapshot/cypher-parameters.html