Hi stackoverflow community. I hope somebody can help me out with some JSON structuring problem. I'm very new to jq, so this problem is a very though one for me...
I have a JSON with the following structure
{
"a": {
"b": {
"1": {
"anyKey1": {
"value": {
"fontFamily": "value1",
"fontWeight": "value2",
"lineHeight": "value3",
"fontSize": "value4",
"letterSpacing": "value5",
"textDecoration": "value6",
"textCase": "value7"
},
"type": "typography"
}
}
},
"anyKey2": {
"value": {
"fontFamily": "value1",
"fontWeight": "value2",
"lineHeight": "value3",
"fontSize": "value4",
"letterSpacing": "value5",
"textDecoration": "value6",
"textCase": "value7"
},
"type": "typography"
}
}
}
I need to change it to the following structure wherever in a JSON the above structure is appearing:
{
"a": {
"b": {
"1": {
"anyKey1": {
"fontFamily": {
"value": "value1",
"type": "typography"
},
"fontWeight": {
"value": "value2",
"type": "typography"
},
"lineHeight": {
"value": "value3",
"type": "typography"
},
"fontSize": {
"value": "value4",
"type": "typography"
},
"letterSpacing": {
"value": "value5",
"type": "typography"
},
"textDecoration": {
"value": "value6",
"type": "typography"
},
"textCase": {
"value": "value7",
"type": "typography"
}
}
}
},
"anyKey2": {
"fontFamily": {
"value": "value1",
"type": "typography"
},
"fontWeight": {
"value": "value2",
"type": "typography"
},
"lineHeight": {
"value": "value3",
"type": "typography"
},
"fontSize": {
"value": "value4",
"type": "typography"
},
"letterSpacing": {
"value": "value5",
"type": "typography"
},
"textDecoration": {
"value": "value6",
"type": "typography"
},
"textCase": {
"value": "value7",
"type": "typography"
}
}
}
}
The rest of the JSON should keep unmodified. I hope some jq expert can help me out here. :)
PS: Thanks to pmf for the given answer, it was already very helpful to understand the way jq works. But I need it more dynamic, because I don't now always the naming of the keys. The only keys I always know is value and type. Therefore I also edited my question a little bit.
I tried myself already a lot to get my needed result, but I couldn't succeed till now. :(
Use walk to recursively visit each subitem. With each visit, select only those objects that have fields called value and type which are of type "object" and "string", respectively. Update (|=) these objects by first storing their .type field in a variable $type. Then, consider the .value field, and modify each of its fields by updating (|=) them to an object using their original value . and the previously stored $type variable.
walk(
(objects | select([.value, .type | type] == ["object","string"])) |=
(.type as $type | .value | with_entries(.value |= {value: ., $type}))
)
{
"a": {
"b": {
"1": {
"anyKey1": {
"fontFamily": {
"value": "value1",
"type": "typography"
},
"fontWeight": {
"value": "value2",
"type": "typography"
},
"lineHeight": {
"value": "value3",
"type": "typography"
},
"fontSize": {
"value": "value4",
"type": "typography"
},
"letterSpacing": {
"value": "value5",
"type": "typography"
},
"textDecoration": {
"value": "value6",
"type": "typography"
},
"textCase": {
"value": "value7",
"type": "typography"
}
}
}
},
"anyKey2": {
"fontFamily": {
"value": "value1",
"type": "typography"
},
"fontWeight": {
"value": "value2",
"type": "typography"
},
"lineHeight": {
"value": "value3",
"type": "typography"
},
"fontSize": {
"value": "value4",
"type": "typography"
},
"letterSpacing": {
"value": "value5",
"type": "typography"
},
"textDecoration": {
"value": "value6",
"type": "typography"
},
"textCase": {
"value": "value7",
"type": "typography"
}
}
}
}
Demo
Related
The following JSON contains a Nested attribute with the name “result”, which contains an array of Key-Value pairs.
{
"result": [
[
{
"key": "projects.name",
"value": "Project 1",
"type": "TEXT"
},
{
"key": "projects.status",
"value": "Archived",
"type": "ENUM"
},
{
"key": "user_tasks.start_date",
"value": "2021-07-08 11:59:34",
"type": "DATETIME"
},
{
"key": "user_tasks.name",
"value": "Section 1",
"type": "TEXT"
},
{
"key": "track_user.duration",
"value": "00:40:02",
"type": "INT"
},
{
"key": "project_sections.question_count",
"value": "24",
"type": "SMALLINT"
},
{
"key": "project_sections.assigned_to_users",
"value": "test1#abc.com",
"type": "JSON"
}
],
[
{
"key": "projects.name",
"value": "Project 2",
"type": "TEXT"
},
{
"key": "projects.status",
"value": "Archived",
"type": "ENUM"
},
{
"key": "user_tasks.start_date",
"value": "2021-07-08 11:59:34",
"type": "DATETIME"
},
{
"key": "user_tasks.name",
"value": "Section 2",
"type": "TEXT"
},
{
"key": "track_user.duration",
"value": "00:40:02",
"type": "INT"
},
{
"key": "project_sections.question_count",
"value": "23",
"type": "SMALLINT"
},
{
"key": "project_sections.assigned_to_users",
"value": "test1#abc.com",
"type": "JSON"
}
],
[
{
"key": "projects.name",
"value": "Project 3",
"type": "TEXT"
},
{
"key": "projects.status",
"value": "Archived",
"type": "ENUM"
},
{
"key": "user_tasks.start_date",
"value": "2021-07-20 21:30:00",
"type": "DATETIME"
},
{
"key": "user_tasks.name",
"value": "Internal Due Date",
"type": "TEXT"
},
{
"key": "track_user.duration",
"value": "21:22:49",
"type": "INT"
},
{
"key": "project_sections.question_count",
"value": "0",
"type": "SMALLINT"
},
{
"key": "project_sections.assigned_to_users",
"value": "test1#abc.com",
"type": "JSON"
}
]
}
Now, what I want is to expand this JSON, and have all the Keys in the Nested array section, like in the “Expected Output” section below using Spark SQL / Scala:
I tried using explode and pivot functions but it's not working properly.
I tried your problem here is the solution.
import org.apache.spark.sql.functions._
import spark.implicits._
import org.apache.spark.sql.expressions._
val DF= spark.read.json(spark.createDataset(json_ip::Nil))
display(
DF.select(explode($"result"))
.withColumn("r_num",row_number over(Window.orderBy($"col")))
.withColumn("res_exp", explode($"col"))
.drop($"col")
.withColumn("all_row_values",$"res_exp.value")
.withColumn("columns",$"res_exp.key")
.drop("res_exp")
.groupBy($"r_num")
.pivot($"columns")
.agg(first($"all_row_values"))
.drop("r_num")
)
output:
I have created a json file with the output having key values pair. But I would like to filter more and get only specific tags and get new output in table using excel (csv) format
aws resourcegroupstaggingapi get-resources --tags-per-page 100 --tag-filters Key=ProjectName,Values=Avengers > tag-filter.json
However it provides the list of all the tags besides "ProjectName". I would like to filter the output with 2 more tags with their values but not all of them:
Actual results:
{
"ResourceTagMappingList": [
{
"ResourceARN": "arn:aws:app:us-east-1:XXXX/mesh/Avenger1",
"Tags": [
{
"Key": "ApplicationName",
"Value": "HULK"
},
{
"Key": "Owner",
"Value": "Mark Ruffalo"
},
{
"Key": "Costume",
"Value": "GREEN"
},
{
"Key": "Power",
"Value": "SMASH"
},
{
"Key": "ProjectName",
"Value": "Avengers"
}
]
},
{
"ResourceARN": "arn:aws:app:us-east-1:XXXX:mesh/Avenger2",
"Tags": [
{
"Key": "ApplicationName",
"Value": "IRON-MAN"
},
{
"Key": "Owner",
"Value": "Robert Downey Jr."
},
{
"Key": "Costume",
"Value": "RED"
},
{
"Key": "Power",
"Value": "SuperSonic"
},
{
"Key": "ProjectName",
"Value": "Avengers"
}
]
}
]
}
Expected Results:
{
"ResourceTagMappingList": [
{
"ResourceARN": "arn:aws:app:us-east-1:XXXX/mesh/Avenger1",
"Tags": [
{
"Key": "ApplicationName",
"Value": "HULK"
},
{
"Key": "Owner",
"Value": "Mark Ruffalo"
},
{
"Key": "ProjectName",
"Value": "Avengers"
}
]
},
{
"ResourceARN": "arn:aws:app:us-east-1:XXXX:mesh/Avenger2",
"Tags": [
{
"Key": "ApplicationName",
"Value": "IRON-MAN"
},
{
"Key": "Owner",
"Value": "Robert Downey Jr."
},
{
"Key": "ProjectName",
"Value": "Avengers"
}
]
}
]
}
To achieve the "expected" output given the "actual" output, you could use the following filter:
.ResourceTagMappingList[].Tags
|= map(select(.Key|IN("ApplicationName","Owner","ProjectName")))
To achieve the expected CSV, it would be helpful to know what you expect.
I'm trying to use jp#gc - JSON/YAML Path Assertion, when my Response Body is:
[
{
"label": "Alabama",
"value": "AL"
},
{
"label": "Alaska",
"value": "AK"
},
{
"label": "American Samoa",
"value": "AS"
},
{
"label": "Arizona",
"value": "AZ"
},
{
"label": "Arkansas",
"value": "AR"
},
{
"label": "California",
"value": "CA"
},
{
"label": "Colorado",
"value": "CO"
},
{
"label": "Connecticut",
"value": "CT"
},
{
"label": "Delaware",
"value": "DE"
},
{
"label": "District Of Columbia",
"value": "DC"
},
{
"label": "Federated States Of Micronesia",
"value": "FM"
},
{
"label": "Florida",
"value": "FL"
},
{
"label": "Georgia",
"value": "GA"
},
{
"label": "Guam",
"value": "GU"
},
{
"label": "Hawaii",
"value": "HI"
},
{
"label": "Idaho",
"value": "ID"
},
{
"label": "Illinois",
"value": "IL"
},
{
"label": "Indiana",
"value": "IN"
},
{
"label": "Iowa",
"value": "IA"
},
{
"label": "Kansas",
"value": "KS"
},
{
"label": "Kentucky",
"value": "KY"
},
{
"label": "Louisiana",
"value": "LA"
},
{
"label": "Maine",
"value": "ME"
},
{
"label": "Marshall Islands",
"value": "MH"
},
{
"label": "Maryland",
"value": "MD"
},
{
"label": "Massachusetts",
"value": "MA"
},
{
"label": "Michigan",
"value": "MI"
},
{
"label": "Minnesota",
"value": "MN"
},
{
"label": "Mississippi",
"value": "MS"
},
{
"label": "Missouri",
"value": "MO"
},
{
"label": "Montana",
"value": "MT"
},
{
"label": "Nebraska",
"value": "NE"
},
{
"label": "Nevada",
"value": "NV"
},
{
"label": "New Hampshire",
"value": "NH"
},
{
"label": "New Jersey",
"value": "NJ"
},
{
"label": "New Mexico",
"value": "NM"
},
{
"label": "New York",
"value": "NY"
},
{
"label": "North Carolina",
"value": "NC"
},
{
"label": "North Dakota",
"value": "ND"
},
{
"label": "Northern Mariana Islands",
"value": "MP"
},
{
"label": "Ohio",
"value": "OH"
},
{
"label": "Oklahoma",
"value": "OK"
},
{
"label": "Oregon",
"value": "OR"
},
{
"label": "Palau",
"value": "PW"
},
{
"label": "Pennsylvania",
"value": "PA"
},
{
"label": "Puerto Rico",
"value": "PR"
},
{
"label": "Rhode Island",
"value": "RI"
},
{
"label": "South Carolina",
"value": "SC"
},
{
"label": "South Dakota",
"value": "SD"
},
{
"label": "Tennessee",
"value": "TN"
},
{
"label": "Texas",
"value": "TX"
},
{
"label": "Utah",
"value": "UT"
},
{
"label": "Vermont",
"value": "VT"
},
{
"label": "Virgin Islands",
"value": "VI"
},
{
"label": "Virginia",
"value": "VA"
},
{
"label": "Washington",
"value": "WA"
},
{
"label": "West Virginia",
"value": "WV"
},
{
"label": "Wisconsin",
"value": "WI"
},
{
"label": "Wyoming",
"value": "WY"
}
]
Here is how is use the JSON/YAML Path Assertion:
but I'm getting Assertion failure:
The following setup should work for you:
More information:
JsonPath - Getting Started
Perl 5 Regex Cheat sheet
The New JSON/YAML Plugin - Using YAML in JMeter
Use JSON Assertion ( jp#gc - JSON/YAML is deprecated)
JSON start with array so use JSON Path
$.[0].label
You can also uncheck Match as regular expression
How can I check that for every array item, which has in the property field1the value Value1, the property field2 is required?
If field1 has another value than Value1 then only field1 is required.
Here is an example:
{
"property_abc":[
{
"field1":"Value1",
"field2": "Value2"
},
{
"field1":"Value2"
},
{
"field1":"Value3"
}
]
}
And this is my Schema:
{
"$schema": "http://json-schema.org/draft-07/schema",
"additionalProperties": false,
"properties": {
"property_abc": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field1": {
"enum": [
"Value1",
"Value2",
"Value3"
],
"type": "string"
},
"field2": {
"enum": [
"Value1",
"Value2",
"Value3"
],
"type": "string"
}
},
"allOf": [
{
"if": {
"properties": {
"property_abc": {
"items": {
"properties": {
"field1": {
"const": "Value1"
}
}
}
}
}
},
"then": {
"required": [
"field1",
"field2"
]
},
"else": {
"required": [
"field1"
]
}
}
]
}
},
"property_xyz": {
"type": "number"
}
},
"type": "object"
}
The above example is correct.
But the following one will throw an error, because for the first item in property_abc the property field2 is required, but not existing:
{
"property_abc":[
{
"field1":"Value1"
},
{
"field1":"Value2"
},
{
"field1":"Value3"
}
]
}
the if schema you have is looking in the wrong place - this schema applies to the object inside the array value of property_abc. I've pasted the correction below, and also moved it outside the allOf which serves no purpose here.
you might also have a look at the dependencies keyword, it might be helpful, but would take a bit of refactoring to express the constraints you have.
{
"$schema": "http://json-schema.org/draft-07/schema",
"additionalProperties": false,
"properties": {
"property_abc": {
"type": "array",
"items": {
"type": "object",
"properties": {
"field1": {
"enum": [
"Value1",
"Value2",
"Value3"
],
"type": "string"
},
"field2": {
"enum": [
"Value1",
"Value2",
"Value3"
],
"type": "string"
}
},
"if": {
"properties": {
"field1": {
"const": "Value1"
}
}
},
"then": {
"required": [
"field1",
"field2"
]
},
"else": {
"required": [
"field1"
]
}
}
},
"property_xyz": {
"type": "number"
}
},
"type": "object"
}
I have the following in a Bookshelf Model
create (data, options = {}) {
return this.forge(data)
.save(null, options);
},
findOne (data, options = {}) {
return this.forge(data).fetch(options);
},
findOrCreate (data, options = {}) {
let createOpts = _.clone(data);
let findOpts = _.pick(data, 'name', 'id');
return this.findOne(findOpts, options)
.then(model => {
return model ? model : this.create(createOpts, options);
});
}
I have a controller with a method that calls to the findOrCreate method like so:
function insertRows(ScenesCollection, Location) {
return config => {
const payload = config.payload;
const projectId = config.project.get('id');
const userId = config.userId;
let inserts = filterImportPayload(payload);
let inserted = [];
_.forEach(inserts, obj => {
let opts = extractOptions(obj, projectId);
let sceneOpts = _.omit(opts, 'location');
_.extend(sceneOpts, {
create_user: config.userId,
update_user: config.userId
});
if (obj.location) {
const locOpts = _.pick({
id: obj.location.value.id,
name: _.isObject(obj.location.value) ? undefined : obj.location.value,
project_id: projectId,
create_user: userId,
update_user: userId
}, _.identity);
inserted.push(Location.findOrCreate(locOpts).then(location => {
sceneOpts.location_id = location.get('id');
}).thenReturn(sceneOpts));
} else {
inserted.push(sceneOpts);
}
});
return Bluebird.all(inserted).then(inserts => {
config.inserted = ScenesCollection.forge(inserts).invokeThen('save');
return Bluebird.props(config);
});
}
}
And the payload that comes in from the POST request is
[{
"name": {
"value": "2a",
"type": "data"
},
"slugline": {
"value": "The Linten Bakery.",
"type": "data"
},
"description": {
"value": "Mary is a hastily prepared but surprisingly breakfast. :)",
"type": "data"
},
"story_day": {
"value": 2,
"type": "data"
},
"page_count": {
"value": 1.5,
"type": "data"
},
"location": {
"type": "matched",
"value": {
"id": 149
}
},
"day_night": {
"type": "matched",
"value": {
"id": 10
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 26
}
},
"extras_count": {
"value": 3,
"type": "data"
},
"type": "insert"
}, {
"name": {
"value": "PU 11a",
"type": "data"
},
"slugline": {
"value": "Office. Not good. But worth it.asd",
"type": "data"
},
"description": {
"value": "asd",
"type": "data"
},
"story_day": {
"value": 1,
"type": "data"
},
"page_count": {
"value": 1,
"type": "data"
},
"location": {
"type": "matched",
"value": {
"id": 149
}
},
"day_night": {
"type": "matched",
"value": {
"id": 10
}
},
"int_ext": {
"value": null,
"type": "ignore"
},
"extras_count": {
"value": 16,
"type": "data"
},
"type": "insert"
}, {
"name": {
"value": "PU 1",
"type": "data"
},
"slugline": {
"value": "Hallwayadqwe",
"type": "data"
},
"description": {
"value": "Mary goes to the kitchennettie.ads",
"type": "data"
},
"story_day": {
"value": 1,
"type": "data"
},
"page_count": {
"value": 1.75,
"type": "data"
},
"location": {
"type": "matched",
"value": {
"id": 149
}
},
"day_night": {
"type": "matched",
"value": {
"id": 10
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 26
}
},
"extras_count": {
"value": 1,
"type": "data"
},
"type": "insert"
}, {
"name": {
"value": "PU 11b",
"type": "data"
},
"slugline": {
"value": "Officeqe",
"type": "data"
},
"description": {
"value": "Extras enter office, causing commotionads",
"type": "data"
},
"story_day": {
"value": 1,
"type": "data"
},
"page_count": {
"value": 0.5,
"type": "data"
},
"location": {
"value": "The Cinema",
"type": "insert"
},
"day_night": {
"type": "matched",
"value": {
"id": 10
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 26
}
},
"extras_count": {
"value": 15,
"type": "data"
},
"type": "insert"
}, {
"name": {
"value": "443",
"type": "data"
},
"slugline": {
"value": "Office",
"type": "data"
},
"description": {
"value": "Wide of Mary standing in what remains of the officeasd",
"type": "data"
},
"story_day": {
"value": "",
"type": "ignore"
},
"page_count": {
"value": 1,
"type": "data"
},
"location": {
"value": "Milwaukee General Hospital",
"type": "insert"
},
"day_night": {
"type": "matched",
"value": {
"id": 10
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 26
}
},
"extras_count": {
"value": 0,
"type": "ignore"
},
"type": "insert"
}, {
"name": {
"value": "PU 6",
"type": "data"
},
"slugline": {
"value": "Office",
"type": "data"
},
"description": {
"value": "Mary walks up to office, out of breath. asd",
"type": "data"
},
"story_day": {
"value": 1,
"type": "data"
},
"page_count": {
"value": 0.5,
"type": "data"
},
"location": {
"value": "My Room",
"type": "insert"
},
"day_night": {
"type": "matched",
"value": {
"id": 10
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 26
}
},
"extras_count": {
"value": "",
"type": "ignore"
},
"type": "insert"
}, {
"name": {
"value": "PU 9",
"type": "data"
},
"slugline": {
"value": "Office/radio",
"type": "data"
},
"description": {
"value": "Mary enjoying listening to her radio at a reasonable volume.ads",
"type": "data"
},
"story_day": {
"value": 1,
"type": "data"
},
"page_count": {
"value": 0.5,
"type": "data"
},
"location": {
"value": "My Room",
"type": "insert"
},
"day_night": {
"type": "matched",
"value": {
"id": 10
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 26
}
},
"type": "insert"
}, {
"name": {
"value": "PU 8b",
"type": "data"
},
"slugline": {
"value": "Office",
"type": "data"
},
"description": {
"value": "Mary converses with Alice outside her officead",
"type": "data"
},
"story_day": {
"value": 1,
"type": "data"
},
"page_count": {
"value": 2.5,
"type": "data"
},
"location": {
"value": "The Cinema",
"type": "insert"
},
"day_night": {
"type": "matched",
"value": {
"id": 10
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 26
}
},
"type": "insert"
}, {
"name": {
"value": "PU 5a",
"type": "data"
},
"slugline": {
"value": "Street",
"type": "data"
},
"description": {
"value": "Wide of mary and child with ballasd",
"type": "data"
},
"story_day": {
"value": 1,
"type": "data"
},
"page_count": {
"value": 1,
"type": "data"
},
"location": {
"value": "My Room",
"type": "insert"
},
"day_night": {
"type": "matched",
"value": {
"id": 11
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 26
}
},
"extras_count": {
"value": 1,
"type": "data"
},
"type": "insert"
}, {
"name": {
"value": "3a",
"type": "data"
},
"slugline": {
"value": "Outside Door",
"type": "data"
},
"description": {
"value": "Mary exits the house",
"type": "data"
},
"story_day": {
"value": 1,
"type": "data"
},
"page_count": {
"value": 0.5,
"type": "data"
},
"location": {
"type": "matched",
"value": {
"id": 491
}
},
"day_night": {
"type": "matched",
"value": {
"id": 10
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 26
}
},
"extras_count": {
"value": 0,
"type": "ignore"
},
"type": "insert"
}, {
"name": {
"value": "2b",
"type": "data"
},
"slugline": {
"value": "Mary's Kitchen",
"type": "data"
},
"description": {
"value": "Mary begins to prepare a second breakfast.",
"type": "data"
},
"story_day": {
"value": 1,
"type": "data"
},
"page_count": {
"value": 1.125,
"type": "data"
},
"day_night": {
"type": "matched",
"value": {
"id": 10
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 27
}
},
"extras_count": {
"value": 1,
"type": "data"
},
"type": "insert"
}, {
"name": {
"value": "83",
"type": "data"
},
"slugline": {
"value": "Office",
"type": "data"
},
"description": {
"value": "Carsten enters Mary's office, informs her she will need to relocate downstairs.",
"type": "data"
},
"story_day": {
"value": 1,
"type": "data"
},
"page_count": {
"value": 0.5,
"type": "data"
},
"location": {
"value": "My Room",
"type": "insert"
},
"day_night": {
"type": "matched",
"value": {
"id": 10
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 26
}
},
"extras_count": {
"value": 0,
"type": "ignore"
},
"type": "insert"
}, {
"name": {
"value": "333",
"type": "data"
},
"slugline": {
"value": "COLLISIUM WEST",
"type": "data"
},
"description": {
"value": "There is a large explosion and then people start running out of the building",
"type": "data"
},
"story_day": {
"value": 10,
"type": "data"
},
"page_count": {
"value": 0,
"type": "ignore"
},
"location": {
"value": "Milwaukee General Hospital",
"type": "insert"
},
"day_night": {
"value": null,
"type": "ignore"
},
"int_ext": {
"type": "matched",
"value": {
"id": 27
}
},
"extras_count": {
"value": 12,
"type": "data"
},
"type": "insert"
}, {
"name": {
"value": "43",
"type": "data"
},
"slugline": {
"value": "I love THAT",
"type": "data"
},
"description": {
"value": "bbg",
"type": "data"
},
"story_day": {
"value": 12,
"type": "data"
},
"page_count": {
"value": 0,
"type": "ignore"
},
"location": {
"value": "Milwaukee General Hospital",
"type": "insert"
},
"day_night": {
"type": "matched",
"value": {
"id": 11
}
},
"int_ext": {
"type": "matched",
"value": {
"id": 27
}
},
"extras_count": {
"value": 10,
"type": "data"
},
"type": "insert"
}]
The problem I am having is that the findOrCreate method is creating multiple records of the same location.