I searched across many sources but could not find the answer to this one..
Its a know fact that a JSONObject keys are returned in reverse order.
Is there any way to recurse through a JSONObject in the correct order as appearing in JSON
String json;
JSONObject obj = new JSONObject(json)
Iterator<String> keys = json.keys() ---> order is reversed
I understand JSONObject is unordered, perhaps there is a way to order it????
JSON is of type below..and the keys start getting recursed from the bottom most styleHint tag
"sections": {
"1": {
"1": {
"1": {
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
}
},
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
}
},
"2": {
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
}
},
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
},
"2": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
}
},
"2": {
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
},
"anchor":"xxx"
},
"3": {
"1": {
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"tag": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
},
"styleHint": {
"tag": {
"name": "xxx",
"title": "xxx",
"id": "xxx"
}
}
}
},
"title": "xxx",
"text": "xxx",
"tags": {
"audience": {
"1": {
"name": "xxx",
"title": "xxx",
"id": "xxxx"
}
},
"styleHint": {
"1": {
"name": "xx",
"title": "xxx",
"id": "xxxx"
}
}
}
}
}
How about that
Get your org.json.JSONObject source and change these
public ListIterator keys() {
ListIterator iter = new ArrayList(this.keySet()).listIterator();
return iter;
}
and
/**
* Construct an empty JSONObject.
*/
public JSONObject() {
this.map = new LinkedHashMap();
}
and
/**
* The map where the JSONObject's properties are kept.
*/
private final LinkedHashMap map;
and
public JSONObject(Map map) {
this.map = new LinkedHashMap();
if (map != null) {
Iterator i = map.entrySet().iterator();
while (i.hasNext()) {
Map.Entry e = (Map.Entry) i.next();
Object value = e.getValue();
if (value != null) {
this.map.put(e.getKey(), wrap(value));
}
}
}
}
I hope I don't burn in hell for that.
Related
I am trying to validate a json payload against a swagger file that contains the service agreement. I am using the json-schema-validator(2.1.7) library to achieve this, but at the moment it's not validating against the specified patterns or min/max length.
Java Code:
public void validateJsonData(final String jsonData) throws IOException, ProcessingException {
ClassLoader classLoader = getClass().getClassLoader();
File jsonSchemaFile = new File (classLoader.getResource("coachingStatusUpdate.json").getFile());
String jsonSchema = new String(Files.readAllBytes(jsonSchemaFile.toPath()));
final JsonNode dataNode = JsonLoader.fromString(jsonData);
final JsonNode schemaNode = JsonLoader.fromString(jsonSchema);
final JsonSchemaFactory factory = JsonSchemaFactory.byDefault();
JsonValidator jsonValidator = factory.getValidator();
ProcessingReport report = jsonValidator.validate(schemaNode, dataNode);
System.out.println(report);
if (!report.toString().contains("success")) {
throw new ProcessingException (
report.toString());
}
}
Message I am sending through
{
"a": "b",
"c": "d",
"e": -1,
"f": "2018-10-30",
"g": "string" }
The swagger definition:
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "Test",
"termsOfService": "http://www.test.co.za",
"license": {
"name": "Test"
}
},
"host": "localhost:9001",
"basePath": "/test/",
"tags": [
{
"name": "controller",
"description": "Submission"
}
],
"paths": {
"/a": {
"put": {
"tags": [
"controller"
],
"summary": "a",
"operationId": "aPUT",
"consumes": [
"application/json;charset=UTF-8"
],
"produces": [
"application/json;charset=UTF-8"
],
"parameters": [
{
"in": "body",
"name": "aRequest",
"description": "aRequest",
"required": true,
"schema": {
"$ref": "#/definitions/aRequest"
}
}
],
"responses": {
"200": {
"description": "Received",
"schema": {
"$ref": "#/definitions/a"
}
},
"400": {
"description": "Bad Request"
},
"401": {
"description": "Unauthorized"
},
"408": {
"description": "Request Timeout"
},
"500": {
"description": "Generic Error"
},
"502": {
"description": "Bad Gateway"
},
"503": {
"description": "Service Unavailable"
}
}
}
}
},
"definitions": {
"aRequest": {
"type": "object",
"required": [
"a",
"b",
"c",
"d"
],
"properties": {
"a": {
"type": "string",
"description": "Status",
"enum": [
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h"
]
},
"aReason": {
"type": "string",
"description": "Reason",
"enum": [
"a",
"b",
"c",
"d",
"e",
"f",
"g",
"h",
"i",
"j",
"k",
"l",
"m",
"n"
]
},
"correlationID": {
"type": "integer",
"format": "int32",
"description": "",
"minimum": 1,
"maximum": 9999999
},
"effectiveDate": {
"type": "string",
"format": "date",
"description": ""
},
"f": {
"type": "string",
"description": "",
"minLength": 1,
"maxLength": 100
}
}
},
"ResponseEntity": {
"type": "object",
"properties": {
"body": {
"type": "object"
},
"statusCode": {
"type": "string",
"enum": [
"100",
"101",
"102",
"103",
"200",
"201",
"202",
"203",
"204",
"205",
"206",
"207",
"208",
"226",
"300",
"301",
"302",
"303",
"304",
"305",
"307",
"308",
"400",
"401",
"402",
"403",
"404",
"405",
"406",
"407",
"408",
"409",
"410",
"411",
"412",
"413",
"414",
"415",
"416",
"417",
"418",
"419",
"420",
"421",
"422",
"423",
"424",
"426",
"428",
"429",
"431",
"451",
"500",
"501",
"502",
"503",
"504",
"505",
"506",
"507",
"508",
"509",
"510",
"511"
]
},
"statusCodeValue": {
"type": "integer",
"format": "int32"
}
}
}
}
}
As you can see I am sending through a correlationID of -1, which should fail validation, but at the moment is's returning as successful:
com.github.fge.jsonschema.report.ListProcessingReport: success
I suggest using this library, which worked for me:
https://github.com/bjansen/swagger-schema-validator
Example:
invalid-pet.json
{
"id": 0,
"category": {
"id": 0,
"name": "string"
},
"named": "doggie",
"photoUrls": [
"string"
],
"tags": [
{
"id": 0,
"name": "string"
}
],
"status": "available"
}
My SchemaParser:
#Component
public class SchemaParser {
private Logger logger = LoggerFactory.getLogger(getClass());
public boolean isValid(String message, Resource schemaLocation) {
try (InputStream inputStream = schemaLocation.getInputStream()) {
SwaggerValidator validator = SwaggerValidator.forJsonSchema(new InputStreamReader(inputStream));
ProcessingReport report = validator.validate(message, "/definitions/Pet");
return report.isSuccess();
} catch (IOException e) {
logger.error("IOException", e);
return false;
} catch (ProcessingException e) {
e.printStackTrace();
return false;
}
}
}
A test:
#Test
void shouldFailValidateWithPetstoreSchema() throws IOException {
final Resource validPetJson = drl.getResource("http://petstore.swagger.io/v2/swagger.json");
try (Reader reader = new InputStreamReader(validPetJson.getInputStream(), UTF_8)) {
final String petJson = FileCopyUtils.copyToString(reader);
final boolean valid = schemaParser.isValid(petJson, petstoreSchemaResource);
assertFalse(valid);
}
}
json-schema-validator seems to work with pure JSON Schema only. OpenAPI Specification uses an extended subset of JSON Schema, so the schema format is different. You need a library that can validate specifically against OpenAPI/Swagger definitions, such as Atlassian's swagger-request-validator.
response:
[
{
"id": "e9299032e8a34d168def176af7d62da3",
"createdAt": "Nov 8, 2017 9:46:40 AM",
"model": {
"id": "eeed0b6733a644cea07cf4c60f87ebb7",
"name": "color",
"app_id": "main",
"created_at": "May 11, 2016 11:35:45 PM",
"model_version": {}
},
"input": {
"id": "df6eae07cd86483f811c5a2202e782eb",
"data": {
"concepts": [],
"metadata": {},
"image": {
"url": "http://www.sachinmittal.com/wp-content/uploads/2017/04/47559184-image.jpg"
}
}
},
"data": [
{
"hex": "#f59b2d",
"webSafeHex": "#ffa500",
"webSafeColorName": "Orange",
"value": 0.0605
},
{
"hex": "#3f1303",
"webSafeHex": "#000000",
"webSafeColorName": "Black",
"value": 0.2085
},
{
"hex": "#a33303",
"webSafeHex": "#8b0000",
"webSafeColorName": "DarkRed",
"value": 0.3815
},
{
"hex": "#000000",
"webSafeHex": "#000000",
"webSafeColorName": "Black",
"value": 0.34275
},
{
"hex": "#f7ce93",
"webSafeHex": "#ffdead",
"webSafeColorName": "NavajoWhite",
"value": 0.00675
}
],
"status": {}
}
]
need to parse this reponse in json. Please help me out.
You can try something like this..
try{
JSONArray array= new JSONArray(Yourresponse);
for(int i=0; i<=array.length();i++){
JSONObject jsonObject=array.getJSONObject(i);
String id= jsonObject.getString("id");
String created_at= jsonObject.getString("createdAt");
String model_id = jsonObject.getJSONObject("model").getString("id");
String app_id=jsonObject.getJSONObject("model").getString("app_id");
//So On... Depends on your requirements. It's just an idea!
}
}
catch (Exception e){
e.printStackTrace();
}
I am using retrofit2 to Make network request,I have searched over here but my bad luck i couldn't find any working solution. that's why i am putting my question here.
my JSON response is given below.
The problem is sometimes the REST API returns an Array of hour , but sometimes it is just a Object. How does one handle such a situation?
Is there an elegant way to handle a mixed array like this in Retrofit/Gson? I'm not responsible for the data coming from the API, so I don't think changing that will be an option.Any help would be appreciated.
{
"status": "success",
"data": [
{
"id": 30,
"name": "Rh.poutiqe",
"global_delay": "0",
"approved": true,
"min_order": "0.000",
"has_pickup": 0,
"address": {
"id": "35",
"name": "Store Address",
"type": "house",
"block_number": "8",
"street": "85",
"avenue": "0",
"building": "2",
"floor": "",
"apartment": "",
"directions": "",
"lat": null,
"lng": null,
"city": {
"id": "79",
"name": "Bayan",
"zone": "3",
"governate": "Hawally"
}
},
"status": "Available",
"owner": {
"id": "32",
"username": "+96550199900",
"creation_date": "2017-08-07 09:46:49",
"info": {
"name": "Asmaa alkandri",
"email": "Asooma_q8#hotmail.com",
"mobile": "50199900",
"store_id": "30",
"device_token": "e01efb2f03cd43509242c7b38ca890471db2e5b056f50b7a3661c34ab45b0b6e"
},
"addresses": [
{
"id": "35",
"name": "Store Address",
"type": "house",
"block_number": "8",
"street": "85",
"avenue": "0",
"building": "2",
"floor": "",
"apartment": "",
"directions": "",
"lat": null,
"lng": null,
"city": {
"id": "79",
"name": "Bayan",
"zone": "3",
"governate": "Hawally"
}
}
]
},
"open": false,
"image": {
"src": "https://api.bits.com.kw/assets/stores/30/y1nzl.jpg"
},
"hours": {
"2": [
{
"id": "117",
"day_id": "2",
"day_of_week": "Tuesday",
"start_hour": "1400",
"end_hour": "2300"
}
],
"3": [
{
"id": "118",
"day_id": "3",
"day_of_week": "Wednesday",
"start_hour": "1400",
"end_hour": "2300"
}
]
},
"next_available": {
"day_of_week": "Tuesday",
"start_hour": "1400",
"end_hour": "2300",
"day_id": "2",
"date": "2017-09-19"
}
},
{
"id": 57,
"name": "RH Kitchen",
"global_delay": "0",
"approved": true,
"min_order": "0.000",
"has_pickup": 0,
"address": {
"id": "63",
"name": "Store Address",
"type": "house",
"block_number": "5",
"street": "2",
"avenue": "",
"building": "97",
"floor": "",
"apartment": "",
"directions": "",
"lat": null,
"lng": null,
"city": {
"id": "79",
"name": "Bayan",
"zone": "3",
"governate": "Hawally"
}
},
"status": "Not Receiving Orders",
"owner": {
"id": "57",
"username": "+96566659454",
"creation_date": "2017-09-09 11:32:19",
"info": {
"name": "RH Kitchen",
"email": "taiba.aldarmi#gmail.com",
"mobile": "66659454",
"store_id": "57",
"device_token": "f6fffd3a393e9aea53863cffbb55b51a3afd2475e952091ea362a85fc930ec9a"
},
"addresses": [
{
"id": "63",
"name": "Store Address",
"type": "house",
"block_number": "5",
"street": "2",
"avenue": "",
"building": "97",
"floor": "",
"apartment": "",
"directions": "",
"lat": null,
"lng": null,
"city": {
"id": "79",
"name": "Bayan",
"zone": "3",
"governate": "Hawally"
}
}
]
},
"open": false,
"image": {
"src": "https://api.bits.com.kw/placeholder.jpg"
},
"hours": [],
"next_available": false
},
{
"id": 64,
"name": "Lets__shop",
"global_delay": "1440",
"approved": true,
"min_order": "5.000",
"has_pickup": 0,
"address": {
"id": "64",
"name": "Store Address",
"type": "house",
"block_number": "3",
"street": "312",
"avenue": "",
"building": "56",
"floor": "",
"apartment": "",
"directions": "",
"lat": "0.000000000000000000",
"lng": "0.000000000000000000",
"city": {
"id": "126",
"name": "Saad Al Abdullah",
"zone": "9",
"governate": "Jahra"
}
},
"status": "Available",
"owner": {
"id": "58",
"username": "+96555899184",
"creation_date": "2017-09-09 18:33:12",
"info": {
"name": "Moneera ibrahim",
"email": "Moneeera96#gmail.com",
"mobile": "55899184",
"store_id": "64",
"device_token": null
},
"addresses": [
{
"id": "64",
"name": "Store Address",
"type": "house",
"block_number": "3",
"street": "312",
"avenue": "",
"building": "56",
"floor": "",
"apartment": "",
"directions": "",
"lat": "0.000000000000000000",
"lng": "0.000000000000000000",
"city": {
"id": "126",
"name": "Saad Al Abdullah",
"zone": "9",
"governate": "Jahra"
}
}
]
},
"open": true,
"next_available": {
"day_of_week": "Today",
"start_hour": "1646",
"end_hour": "2230",
"day_id": "0",
"date": "2017-09-17 1646"
},
"image": {
"src": "https://api.bits.com.kw/assets/stores/64/0xqh4.jpg"
},
"hours": [
[
{
"id": "161",
"day_id": "0",
"day_of_week": "Sunday",
"start_hour": "730",
"end_hour": "2230"
}
],
[
{
"id": "162",
"day_id": "1",
"day_of_week": "Monday",
"start_hour": "730",
"end_hour": "2230"
}
],
[
{
"id": "163",
"day_id": "2",
"day_of_week": "Tuesday",
"start_hour": "730",
"end_hour": "2230"
}
],
[
{
"id": "164",
"day_id": "3",
"day_of_week": "Wednesday",
"start_hour": "730",
"end_hour": "2230"
}
],
[
{
"id": "165",
"day_id": "4",
"day_of_week": "Thursday",
"start_hour": "730",
"end_hour": "2230"
}
],
[
{
"id": "166",
"day_id": "5",
"day_of_week": "Friday",
"start_hour": "730",
"end_hour": "2230"
}
],
[
{
"id": "167",
"day_id": "6",
"day_of_week": "Saturday",
"start_hour": "730",
"end_hour": "2230"
}
]
]
}
]
}
I have Make POJO class like:
public class StoreModel implements Parcelable{
#SerializedName("id")
public int id;
#SerializedName("name")
public String name;
#SerializedName("global_delay")
public String global_delay;
#SerializedName("approved")
public boolean approved;
#SerializedName("min_order")
public String min_order;
#SerializedName("has_pickup")
public int has_pickup;
#SerializedName("address")
public AddressModel address;
#SerializedName("status")
public String status;
#SerializedName("owner")
public OwnerModel owner;
#SerializedName("open")
public boolean open;
#SerializedName("next_available")
public Object next_available;
#SerializedName("image")
public ImageModel image;
protected StoreModel(Parcel in) {
id = in.readInt();
name = in.readString();
global_delay = in.readString();
approved = in.readByte() != 0;
min_order = in.readString();
has_pickup = in.readInt();
address = in.readParcelable(AddressModel.class.getClassLoader());
status = in.readString();
owner = in.readParcelable(OwnerModel.class.getClassLoader());
open = in.readByte() != 0;
image = in.readParcelable(ImageModel.class.getClassLoader());
//next_available = in.readParcelable(NextAvailableModel.class.getClassLoader());
}
public static final Creator<StoreModel> CREATOR = new Creator<StoreModel>() {
#Override
public StoreModel createFromParcel(Parcel in) {
return new StoreModel(in);
}
#Override
public StoreModel[] newArray(int size) {
return new StoreModel[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(id);
parcel.writeString(name);
parcel.writeString(global_delay);
parcel.writeByte((byte) (approved ? 1 : 0));
parcel.writeString(min_order);
parcel.writeInt(has_pickup);
parcel.writeParcelable(address, i);
parcel.writeString(status);
parcel.writeParcelable(owner, i);
parcel.writeByte((byte) (open ? 1 : 0));
parcel.writeParcelable(image, i);
/*if(next_available instanceof NextAvailableModel)
parcel.writeParcelable((NextAvailableModel)next_available, i);
else if(next_available instanceof Boolean)
parcel.writeByte((byte) ((Boolean)next_available ? 1 : 0));*/
}
#SerializedName("hours")
#Expose
public List<List<HoursModel>> hours;
}
**And HoursModel Java Class**
public class HoursModel implements Parcelable{
#SerializedName("id")
public String id;
#SerializedName("day_id")
public String day_id;
#SerializedName("day_of_week")
public String day_of_week;
#SerializedName("start_hour")
public String start_hour;
#SerializedName("end_hour")
public String end_hour;
protected HoursModel(Parcel in) {
id = in.readString();
day_id = in.readString();
day_of_week = in.readString();
start_hour = in.readString();
end_hour = in.readString();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(id);
dest.writeString(day_id);
dest.writeString(day_of_week);
dest.writeString(start_hour);
dest.writeString(end_hour);
}
#Override
public int describeContents() {
return 0;
}
public static final Creator<HoursModel> CREATOR = new Creator<HoursModel>() {
#Override
public HoursModel createFromParcel(Parcel in) {
return new HoursModel(in);
}
#Override
public HoursModel[] newArray(int size) {
return new HoursModel[size];
}
};
}
First, if possible, verify if you can fix this braindead API. :)
First of all, notice that the API returns 2 very different types of data:
list of hours (no keys)
map of hours (each element has a key!)
You'll need to represent this structure in your POJO somehow. Maybe a list of key-hour pairs, like List<Pair<String, Hour>, with nullable key? Your call.
Second, you need to create a custom TypeAdapter that can deserialize a list and/or map into a Java object.
Once you have a type adapter, you can either attach it to a field using #JsonAdapter annotation, or register custom type in Gson builder.
https://google.github.io/gson/apidocs/com/google/gson/annotations/JsonAdapter.html
http://www.javacreed.com/gson-typeadapter-example/
I need sorting for the documents like :
{
customer: {
fullname: "Lorem ipsum"
},
order_number: "12313131",
company: {
name: "Test Inc."
},
date: "10.06.2015 18:00"
}
But as far as I unterstood I can not sort by values in analysed fields. There I am trying to create a mapping :
{
"mappings": {
"_default_": {
"dynamic_templates": [
{
"base": {
"match": "*",
"mapping": {
"type": "multi_field",
"fields": {
"{name}": {"type": "string"},
"_sort": {"type": "string", "analyzer": "sort"}
}
}
}
}
]
}
},
"settings": {
"analysis": {
"analyzer": {
"sort": {
"type": "custom",
"tokenizer": "keyword",
"filter": "lowercase"
}
}
}
}
}
But if I put this configuration, I am getting an exception : ElasticsearchIllegalArgumentException: unknown property. Without this mapping my indexing works fine.
What i want to do is create a multifield called name_sort (not_analysed) so I can sort by values.
****
At leas I can able to create a mapping correctly. My mapping looks like:
{
"muhamo": {
"mappings": {
"bookings": {
"dynamic_templates": [
{
"base": {
"mapping": {
"index": "analyzed",
"type": "{dynamic_type}",
"fields": {
"{name}_sort": {
"index": "not_analyzed",
"type": "{dynamic_type}"
}
}
},
"match": "*",
"match_mapping_type": "string"
}
},
{
"catch_all": {
"mapping": {
"fields": {
"{name}_sort": {
"index": "not_analyzed",
"type": "{dynamic_type}"
}
}
},
"match": "*",
"match_mapping_type": "*"
}
}
],
"properties": {
"bookingType": {
"type": "string",
"fields": {
"bookingType_sort": {
"type": "string",
"index": "not_analyzed"
}
}
},
"comment": {
"type": "string",
"fields": {
"comment_sort": {
"type": "string",
"index": "not_analyzed"
}
}
},
"costLocation": {
"type": "string",
"fields": {
"costLocation_sort": {
"type": "string",
"index": "not_analyzed"
}
}
},
"customer": {
"properties": {
"fullname": {
"type": "string",
"fields": {
"fullname_sort": {
"type": "string",
"index": "not_analyzed"
}
}
}
}
},
"date": {
"type": "string",
"fields": {
"date_sort": {
"type": "string",
"index": "not_analyzed"
}
}
},
"deleted": {
"type": "boolean"
},
"toAirport": {
"type": "boolean"
}
}
}
}
}
}
But if I try to sort my results by customer.fullname_sort I am getting an exception as
query[ConstantScore(*:*)],from[-1],size[-1]: Parse Failure [No mapping found for [customer.fullname_sort] in order to sort on]
You should sort on customer.fullname.fullname_sort. That's the path to your field, according to the mapping of the index.
My mapping is as follows:
{
"mappings": {
"person": {
"properties": {
"lastUpdated": {
"type": "long"
},
"isDeleted": {
"type": "boolean"
},
"person": {
"properties": {
"car": {
"type": "nested",
"properties": {
"model": {
"type": "string"
},
"make": {
"type": "string"
}
}
},
"last_name": {
"type": "string"
},
"first_name": {
"type": "string"
}
}
}
}
}
}
}
I have two documents:
{
"person": {
"first_name": "Bob",
"last_name": "Doe",
"car": [
{
"make": "Saturn",
"model": "Imprezza"
},
{
"make": "Honda",
"model": "Accord"
}
]
},
"isDeleted": false,
"lastUpdated": 1433257051959
}
and
{
"person": {
"first_name": "Zach",
"last_name": "Foobar",
"car": [
{
"make": "Saturn",
"model": "SL"
},
{
"make": "Subaru",
"model": "Imprezza"
}
]
},
"isDeleted": false,
"lastUpdated": 1433257051959
}
I wanted to query the car.make field and so, I wrote the following query:
{
"query": {
"nested": {
"path": "person.person.car",
"query": {
"match": {
"car.make": "Saturn"
}
},
"inner_hits": {}
}
}
}
However, I am not getting anything back results back in return. When I remove the person level object and try to search, then it works. Any idea how to go about doing multi-level nested queries?
EDIT: On the other hand, when I structure my data like this and query then it works.
{
"mappings": {
"person": {
"properties": {
"car": {
"type": "nested",
"properties": {
"model": {
"type": "string"
},
"make": {
"type": "string"
}
}
},
"last_name": {
"type": "string"
},
"first_name": {
"type": "string"
}
}
}
}
}
{
"first_name": "Zach",
"last_name": "Foobar",
"car": [
{
"make": "Saturn",
"model": "SL"
},
{
"make": "Subaru",
"model": "Imprezza"
}
]
}
{
"first_name": "Bob",
"last_name": "Doe",
"car": [
{
"make": "Saturn",
"model": "Imprezza"
},
{
"make": "Honda",
"model": "Accord"
}
]
}
{
"query": {
"nested": {
"path": "person.car",
"query": {
"match": {
"car.make": "Honda"
}
},
"inner_hits": {}
}
}
}
This way the query works. I feel like this has something to do with multi-level nesting. Multi-level nesting is not working.
The nested path attribute needs to be "person.car".
Add "type": "nested", above the (2nd level) person properties line if you wish person to be a nested field type, which is required for Nested Query searches. The default field type is object field.
The naming you are using is confusing, try to rename your mapping not to use person twice.
{
"query": {
"nested": {
"path": "person.car",
"query": {
"match": {
"make": "Saturn"
}
},
"inner_hits": {}
}
}
}