Как я могу выполнить подчиненный фильтр, используя JsonPath?
Я прочитал документацию, и я не могу понять, как я выполняю субфильтр, используя JsonPath. Вот пример...
Учитывая следующий JSON, как мне получить список людей с адресом в Sydney
?
Я пробовал варианты $.people[?(@.addresses[*].city=="Sydney")]
но безрезультатно. например
$.people[?(@.addresses[*].city=="Sydney")]
$.people[?(@.addresses.city=="Sydney")]
$.people[?(@..city=="Sydney")]
JSON
{
"people": [{
"name": "George",
"addresses": [{
"city": "Sydney"
}]
},
{
"name": "Jane",
"addresses": [{
"city": "Brisbane"
}]
},
{
"name": "Fred",
"addresses": [{
"city": "Perth"
},
{
"city": "Sydney"
}
]
}
]
}
Предпочитаемый вывод
{
"people": [{
"name": "George",
"addresses": [{
"city": "Sydney"
}]
},
{
"name": "Fred",
"addresses": [{
"city": "Perth"
},
{
"city": "Sydney"
}
]
}
]
}
Я использую следующую библиотеку Java: com.jayway.jsonpath:json-path:2.2.0
Я использую http://jsonpath.com/ для проверки моего jsonpath в браузере (может, в этом проблема?).
1 ответ
Проблема в том, что @.addresses[*].city
это коллекция. Это не ЛЮБОЙ город человека, и это не ТОЛЬКО (каждый) город человека.
Если вы ищете людей с некоторыми адресами в Сиднее, запрос должен быть:
"$.people[?(\"Sydney\" in @.addresses[*].city)]"
Пример:
String filter = "$.people[?(\"Sydney\" in @.addresses[*].city)]";
ReadContext ctx = JsonPath.parse(json);
List<Map<String, Object>> rez = ctx.read(filter, List.class);
Если вы ищете людей со всеми адресами в Сиднее, я не знаю правильный запрос. Можно использовать Predicate, но это очень сложный код.
Просто для информации:
List<Map<String, Object>> rez = JsonPath.parse(json).read(
"$.people[?]",
List.class,
new Predicate() {
@Override
public boolean apply(PredicateContext ctx) {
Map<String, Object> map = ctx.item(Map.class);
ReadContext readContext = JsonPath.parse(JSONObject.toJSONString(map));
List<String> allAddresses = readContext.read("$.addresses[*].city");
List<String> sydneyAddresses = readContext.read("$.addresses[?(@.city=='Sydney')].city");
return allAddresses.size() == sydneyAddresses.size();
}
});
Сначала создайте фильтр
String jsonData = "{
"people": [{
"name": "George",
"addresses": [{
"city": "Sydney"
}]
},
{
"name": "Jane",
"addresses": [{
"city": "Brisbane"
}]
},
{
"name": "Fred",
"addresses": [{
"city": "Perth"
},
{
"city": "Sydney"
}
]
}
]
}"
Filter expensiveFilter = Filter.filter(Criteria.where(['people'][*]['address']['city'].eq("Sydney"));
Теперь вы можете добавить это в свой JsonPath
String peoples = JsonPath.parse(jsonData).read("$['people'][?]", expensiveFilter).toString();