Search code examples
jsonneo4jcyphergraph-databasesneo4j-apoc

Filter a list with multiple conditions using WITH in Cypher,Neo4j


I'm new to Neo4j. I'm kind of got stuck for loading a JSON file into Neo4j database. I have a list of tags for many transactions. Each transaction tag can have one or two tags: third-party and category.

Here is an example JSON.

{
    "tags": [
        [
            {
                "thirdParty": "Supermarkets"
            },
            {
                "category": "Groceries"
            }
        ],
        [
            {
                "category": "Rent"
            }
        ],
        [
            {
                "thirdParty": "Education"
            },
            {
                "category": "Education"
            }
        ]
        .....
    ]
}

I only want to find objects that have both category and thirdParty(some objects only have one tag).

And here is my code, the list is just a list of categories I want.

CALL apoc.load.json("file:///full.json")
YIELD value
with ['Gambling','Subscription TV','Telecommunications'] as list
UNWIND value.tags as tags
WITH [tag in tags where tag.category IN list AND tag.thirdParty IS NOT NULL] AS temp
RETURN temp

The weird thing is this always return me a list null. But with only one condition then it will work, like only find objects in the list or only thirdParty is not null. But combine the 2 conditions together, it will always return a list of null.

Does anyone know how to fix this?

Thanks


Solution

  • Your UNWIND seems to return a list of maps, not a map. But the good thing is that with apoc, you can convert it easily.

    this works:

    WITH [
            [
                {
                    thirdParty: "Supermarkets"
                },
                {
                    category: "Groceries"
                }
            ],
            [
                {
                    category: "Rent"
                }
            ],
            [
                {
                    thirdParty: "Education"
                },
                {
                    category: "Education"
                }
            ]
        ]
    AS tagsList
    
    WITH tagsList, ['Groceries','Subscription TV','Telecommunications'] as list
    UNWIND tagsList as tags
    WITH list,
         apoc.map.fromPairs(
            REDUCE(arr=[],tag IN tags | 
                   arr+[[keys(tag)[0],tag[keys(tag)[0]]]]
            )
         ) AS tagMap
    WHERE tagMap.category IN list AND tagMap.thirdParty IS NOT NULL
    RETURN tagMap
    

    returns

    {
      "thirdParty": "Supermarkets",
      "category": "Groceries"
    }