1

I have a JSON file, the head of which looks like this:

"exports": {
        "type": "WordsAndPhrases",
        "date": "2018-08-02T10:07:58.047669Z",
        "relevantYears": "2012,2013,2014,2015,2016,2017",
        "Words": {
            "H1": "WORDS AND PHRASES:",
            "Word": [
                {
                    "Phrase": {
                        "id": "phrase_2011001932",
                        "title": "A common"
                    },
                    "Document": "Law of Property Act 1925, s 193(1) (as amended)",
                    "Refs": {
                        "CaseTitle": {
                            "id": "2011201246",
                            "title": "ADM Milling Ltd v Tewkesbury Town Council"
                        },
                        "title": "None",
                        "citations": "Lewison J [2011] EWHC 595 (Ch); [2012] Ch 99; [2011] 3 WLR 674, Ch D"
                    }
                },

I am using the following script to import the JSON data into Neo4J:

import json
from py2neo import Graph, authenticate

authenticate("localhost:7474", "neo4j", "foobar")
graph = Graph()

with open('wp.json') as data_file:
    json = json.load(data_file)

query = """
WITH {json} AS document

UNWIND document.exports.Words.Word AS Word

MERGE (Phrase:a {phrase: Word.Phrase.title})
MERGE (Document:b {document: Word.Document})
FOREACH (case in Word.Refs.CaseTitle.title | MERGE (Report:z {report: case}))
"""

# Send Cypher query.
print (graph.run(query, json = json).dump())

The first two MERGE queries work fine. However, the FOREACH query is proving to be problematic. I'm using the FOREACH query to deal with instances where there are multiple CaseTitle properties in a single block, for example:

{
                    "Phrase": {
                        "id": "phrase_2011002042",
                        "title": "Acts contrary to purposes and principles of United Nations"
                    },
                    "Document": "Council Directive 2004/83/EC, art 12(2)(c)",
                    "Refs": [
                        {
                            "CaseTitle": {
                                "id": "2011201814",
                                "title": "Federal Republic of Germany v B"
                            },
                            "title": "None",
                            "citations": "(Joined Cases C-57/09 and C-101/09); [2012] 1 WLR 1076, ECJ"
                        },
                        {
                            "CaseTitle": {
                                "id": "2016008987",
                                "title": "Commissaire général aux réfugiés et aux apatrides v Lounani"
                            },
                            "title": "None",
                            "citations": "EU:C:2017:71; [2017] 4 WLR 52, ECJ"
                        }
                    ]
                },

When I run the script, the following error occurs:

py2neo.database.status.CypherTypeError: Type mismatch: expected a map but was List{Map{title -> String("None"), CaseTitle -> Map{title -> String("Federal Republic of Germany v B"), id -> String("2011201814")}, citations -> String("(Joined Cases C-57/09 and C-101/09); [2012] 1 WLR 1076, ECJ")}, Map{title -> String("None"), CaseTitle -> Map{title -> String("Commissaire général aux réfugiés et aux apatrides v Lounani"), id -> String("2016008987")}, citations -> String("EU:C:2017:71; [2017] 4 WLR 52, ECJ")}}

The JSON appears to be valid. Can anyone recommend a way of dealing with this error?

DanielH
  • 176
  • 1
  • 16

1 Answers1

0

Instead of Word.Refs.CaseTitle.title you should use Word.Refs[0].CaseTitle.title. In your JSON it is clear that refs is an array, and you're treating it like an object. The error message is saying this -- when it tries to dereference "CaseTitle" under "Refs", it is expecting a map, but what you gave it was a list of maps.

FrobberOfBits
  • 17,634
  • 4
  • 52
  • 86
  • Thanks for this, @FrobberOfBits. I've modified the `FOREACH` query to read: `FOREACH (case in Word.Refs[0].CaseTitle.title | MERGE (Report:z {report: case}))` I'm now seeing a different error, namely: `py2neo.database.status.CypherTypeError: Expected Long(0) to be a org.neo4j.values.storable.TextValue, but it was a org.neo4j.values.storable.LongValue` I'm scratching my head because I would've expect the values in the target property to be recognised as strings? – DanielH Aug 03 '18 at 09:44
  • What's the rest of that error message? This seems like a similar problem -- you need to update the original question to give the updated error and data sample. But the error is rather clear -- cypher thinks that your data contains a long number that you're trying to treat like a string, but it's not a string. To solve this, you have to figure out which number it's seeing in the real data – FrobberOfBits Aug 03 '18 at 15:48