Check existence of an attribute

I want to accumulate node attributes only if it exists.

I am running the following query -

MapAccum<STRING, ListAccum>@@result;

node = select p from some_node:p - (ANY:rel) - :other
ACCUM @@result += (“Level” -> other.level);

But it might be possible that the some of the other nodes(neighbor nodes) might not have level as an attribute, in that case, the above query skips it whereas i want to store it as None.

So, is there any way to check the existence of an attribute? So that I will accumulate the node value only when the attribute exists otherwise value “None” will be accumulated.

Please let me know if this is what you meant:

MapAccum<STRING, ListAccum> @@result;
ListAccum<STRING> @@empty;

node = select p from some_node:p - (ANY:rel) - :other
ACCUM IF other.level.size() != 0 
              THEN @@result += (“Level” -> other.level) 
              ELSE @@result += ("Level" -> @@empty) END;

However, note that this has the same exact functionality as your provided query. Skipping the assignment of your empty ListAccum to the map is the same as actually adding it because the empty assignment will not change anything in the map.

Also, everything in your map is assigned to the key “Level”, which kind of defeats the purpose of a map since you are just treating it like a single list without keys. It would make more sense if you also stored the respective VERTEX (or its primary ID) in the map for assignment.

i.e. (other -> other.level) or (other.id -> other.level)

This way each respective level is mapped to the correct VERTEX, instead of everything being mapped to one key.

@lshestakov Yes, I want to accumulate the level property(or any particular property) only if it exists.
Something like -
ACCUM IF exists(other.level)
THEN @@result += (“Level” -> other.level)
ELSE @@result += (“Level” -> “None”) END;

And with your above approach , the query results in following error -
The identifier ‘other.level’ of unknown type is invalid to call any function.

Also, looks like size only works with list or array.

refer - https://docs.tigergraph.com/dev/gsql-ref/querying/operators-functions-and-expressions#jsonobject-and-jsonarray-functions

It’s necessary for you to store None ? or you just want to resolve the error The identifier ‘other.level’ of unknown type is invalid to call any function?
If you just want to resolve the error you can define start node with (ANY)

create query test (vertex startNode) for graph test_graph{
MapAccum<STRING, ListAccum>@@result;
some_node(ANY)={startNode}
node = select p from some_node:p - (ANY:rel) - :other
ACCUM @@result += (“Level” -> other.level);
}

@wei, Yes it is important for me to store it as None if the property does not exist, But the question remains the same, is there any way to check if a particular property exists for node type i.e. Does the schema of that node type contains the property.

As I know there is no way to check whether a property exists.
But I find a trick !!!

create query test (vertex startNode) for graph test_graph{
MapAccum<STRING, ListAccum<STRING>>@@result;
some_node(ANY)={startNode};
node = select p from some_node:p - (ANY:rel) - :other
ACCUM 
          if other.level==other.level
          then @@result+=("Level"->other.level)
          else @@result+=("Level"->"None")
          end;
}
1 Like

@wei, Thanks. The solution works.

Also, I have found another solution using COALESCE -

create query test (vertex startNode) for graph test_graph{
MapAccum<STRING, ListAccum<STRING>>@@result;

some_node(ANY)={startNode};

node = select p from some_node:p - (ANY:rel) - :other
ACCUM @@results += ("Level"-> COALESCE(other.level, "None"));

}