Как я могу выполнить подчиненный фильтр, используя 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();
Другие вопросы по тегам