So I have this Neo4j database and I made a query like this:
WITH something, collect(field1:aaaa,field2:bbbb) AS d
RETURN something, d
I wanted to get the results and show them with python-tabulate
by creating a subtable of the 'd' fields and then inserting it into a main table. However, when making the subtable I realized something.
In theory, each record should've looked something like this
{
something: "abcd"
d: [{
'field1':"abcd"
'field2':abcd
},
{
'field1':"abcd"
'field2':abcd
} ...etc
]
{
However, when I checked at the response in Python, it turns out that field1 and field2 are in the wrong order, like:
{
something: abcd
d: [{
'field2':"abcd"
'field1':abcd
},
{
'field2':"abcd"
'field1':abcd
} ...etc
]
{
This kinda matters because I wanted to use python-tabulate
to format the output, which should still be possible but I'd have to change the positions of field2 and field 1.
I used print() to look at the records to verify it's not a thing of the tabulate library, which it's not. The fields are already swapped from the response.
So my question is: Why is this happening? Does Cypher prioritize numbers over strings or something like that (I guess it's worth mentioning, field 1 is a string and field 2 an int)? And if so, how do I prevent it?
Your issue is not with COLLECT
, but with maps. Neo4j does not remember the order in which elements were added to maps. This is true for most systems and programming languages.
However, lists do remember the element order. And, since python-tabulate supports tables that are lists of lists, you can just do this in Cypher:
...
RETURN something, COLLECT([aaaa, bbbb]) AS d
and the Python result
would be like something like this:
{
"something": "abcd"
"d": [
["abc", 123],
["def", 456],
...
]
}
With that result
, you just need to pass d
and the appropriate column headers to python-tabulate
. For example:
print(tabulate(result["d"], ["field1", "field2"], tablefmt="plain"))