Skip to content

whereIn with non-sequential keys produces an invalid terms filter (terms_lookup error) #2

Description

@tobiasnitsche

Version

  • directorytree/opensearch-scout-driver: v1.1.0

Description

SearchRequestPayload::makeFilter() builds each terms filter directly from
$builder->whereIns values without reindexing them:

foreach ($builder->whereIns as $field => $values) {
    $filter[] = ['terms' => [$field => $values]];
}

When a values array has non-sequential integer keys, json_encode() serializes it as a
JSON object instead of an array. OpenSearch then reads the object form under terms
as a terms lookup and rejects the request.

This happens with ordinary input — e.g. a values array left keyed by array_unique()
(which preserves keys) or a keyed pluck().

To reproduce

$values = array_unique(['active', 'active', 'invited']); // [0 => 'active', 2 => 'invited']

Model::search('foo')->whereIn('status', $values)->get();

The generated filter becomes:

{ "terms": { "status": { "0": "active", "2": "invited" } } }

Expected

{ "terms": { "status": ["active", "invited"] } }

Actual

OpenSearch returns HTTP 400:

x_content_parse_exception: [1:2039] [terms_lookup] unknown field [1]

Suggested fix

Reindex the values in makeFilter() so a terms filter always serializes as a JSON
array (whereIn means "field is one of this list", so the value is never meant to be an
object / terms lookup):

$filter[] = ['terms' => [$field => array_values($values)]];

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions