Stack Exchange
Malformed Elastic query when defining 2 filters with a multi_match
I am having difficulty, combining a multi_match query with 2 filters.
I am using Elastic 7.17 and am specifying the query with PHP.
The error is as follows:
{
    "error": {
        "root_cause": [{
            "type": "parsing_exception",
            "reason": "[term] malformed query, expected [END_OBJECT] but found [FIELD_NAME]",
            "line": 1,
            "col": 170
        }],
        "type": "x_content_parse_exception",
        "reason": "[1:170] [bool] failed to parse field [filter]",
        "caused_by": {
            "type": "parsing_exception",
            "reason": "[term] malformed query, expected [END_OBJECT] but found [FIELD_NAME]",
            "line": 1,
            "col": 170
        }
    },
    "status": 400
}

The parser is fine with each of the filters individually, if I comment one out, the other works ok, but as soon as I have both uncommented I get an error.
This presumably suggests that it is the way I am defining multiple filters that is the issue?
However, the query I am building is almost exactly the same as an official Elastic example.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/query-filter-context.html
My query is here:
            'query' => [
                'bool' => [
                    'must' => [
                        'multi_match' => [
                            'query' => $keywords,
                            'fields' => [
                                'title^4',
                                'subtitle^4',
                            ]
                        ],
                    ],
                    'filter' => [
                        'term' => [
                            'status' => 'live'
                        ],
                        'range' => [
                            'published_date' => [
                                'lte' => '2022-11-01'
                            ]
                        ]
                    ]
                ]
            ]


The reason it was failing was because of the way I was denoting filters as PHP arrays. For it to be turned into a JSON array, the PHP needed arrays within arrays.
Adding the extra square brackets turns it into a filters array.
            'query' => [
                'bool' => [
                    'must' => [
                        'multi_match' => [
                            'query' => $keywords,
                            'fields' => [
                                'title^4',
                                'subtitle^4',
                            ]
                        ],
                    ],
                    'filter' => [
                        [
                            'term' => [
                                'status' => 'live',
                            ],
                        ],
                        [
                            'range' => [
                                'published_date' => [
                                    'lte' => '2022-11-01'
                                ]
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ];

Helpful with debugging was using the JSON_PRETTY_PRINT constant during json encoding.
$json = json_encode($query, JSON_PRETTY_PRINT);

