Converting 1.7 "terms" with execution "and" query DSL to 2.1.1 due to "terms" breaking changes

The following 1.7 Query DSL (php-client formatted) code makes use of the "terms" filter and execution "and" to require all terms to be found in documents. With the "terms" breaking change in 2.1.1 I need to rewrite the query. It appears that "terms" in 2.1.1 is only good for finding documents with "any" of the terms provided, which raises some questions about how to convert code like this.

  1. Is the new best practice to separate all the "terms" formerly executed with "and" into separate "term" filters, and then wrap all the "term" filters in "and" query? You can see my updated 2.1.1 query below. Seems to work, but I wonder if this is the new best practice for handling of "terms" filtered queries, formerly executed with "and"?

1.7 Query DSL

$query = [
    'query' => [
        'filtered' => [
            'filter' => [
                'bool' => [
                    'must' => [
                        [
                            'term' => [
                                'award_sku' => (string) $data['award_sku']
                            ]
                        ],
                        [
                            'term' => [
                                'class' => (string) $data['class']
                            ]
                        ],
                        [
                            'terms' => [
                                'params' => $data['params'],
                                'execution' => 'and',
                                '_cache' => true
                            ]
                        ],
                        [
                            'term' => [
                                'params_count' => $data['params_count']
                            ]
                        ]
                    ],
                    '_cache' => true
                ]
            ]
        ]
    ]
];

2.1.1 Query DSL (so far)

$query = [
    'query' => [
        'bool' => [
            'filter' => [
                'and' => [
                    [
                        'term' => [
                            'award_sku' => (string) $data['award_sku']
                        ]
                    ],
                    [
                        'term' => [
                            'class' => (string) $data['class']
                        ]
                    ],
                    [
                        'term' => [
                            'params_count' => $data['params_count']
                        ]
                    ],
                    [
                        'term' => [
                            'params' => $param1
                        ]
                    ],
                    [
                        'term' => [
                            'params' => $param2
                        ]
                    ]
                ]
            ]
        ]
    ]
];

Any ideas anybody?

Two main things. First, the and/or/not queries are deprecated, and will be removed in the future. Instead, you can just use a bool with must clauses to replicate the and.

Second, I'd just iterate over $data['params'] and add those individually to the query as mandatory term clauses. It's a bit more work than pre 2.0, but it should give the same result (and'ing a bunch of terms together, effectively). Something like:

$query = [
    'query' => [
        'bool' => [
            'filter' => [
                'bool' => [
                    'must' => [
                        [
                            'term' => [
                                'award_sku' => (string) $data['award_sku']
                            ]
                        ],
                        [
                            'term' => [
                                'class' => (string) $data['class']
                            ]
                        ],
                        [
                            'term' => [
                                'params_count' => $data['params_count']
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ]
];

foreach ($data['params'] as $param) {
  $query['bool']['filter']['bool']['must'][] = [
    'term' => [
      'params' => $param
    ]
  ]
}

polyfractal, as always, thanks for your help.

Np, happy to help! :slight_smile: