4
votes

I have the following function which searches for results in elasticsearch.

I want to do the following request with PHP and Guzzle.

  /**
   * {@inheritdoc}
   */
  public function sendSearchRequest($es_node, $request) {
    try {
      if (isset($es_node)) {
        $ssl = $es_node->get('field_ess_verify_ssl')->value;
        $ssl_val = $ssl ? 'https://' : 'http://';

        $body = [
          'json' => [
            'query' => [
              'bool' => [
                'should' => [
                  [
                    'multi_match' => [
                      'query' => $request->get('search'),
                      'fields' => ['message', 'event.type'],
                      'operator' => 'AND',
                    ],
                  ],
                  [
                    'match' => [
                      'event.type' => $request->get('type'),
                    ],
                  ],
                  [
                    'match' => [
                      'event.labels' => $request->get('label'),
                    ],
                  ],
                ],
              ],
            ],
          ],
        ];

        $response = $this->httpClient->request('POST', $ssl_val . $es_node->get('field_ess_host')->value . ':' . $es_node->get('field_ess_port')->value . '/***/***/_search?pretty', $body)
          ->getBody()
          ->getContents();

        return json_decode($response, TRUE)['hits']['hits'] ?? '';
      }
    } catch (Exception $exception) {
      \Drupal::logger(__METHOD__)->error('No ES node has been found.');
      return FALSE;
    }
  }

But with this i get a parsing exception which means that the multi_match doesn't work this way. If i use a 'normal' match in that place it's working fine but then i am limited to 1 field.

The other match fields uses other form fields for input and that has always one value.

But with form field 'Description search' i want to look in multiple fields with the AND operator.

Anyone knows how to fix this?

Screenshot of the form:

enter image description here

1
Try with double quote inside the multi_match. "multi_match" => [ "query" => $request->get('search'), "fields" => ["message", "event.type"], "operator" => "AND", ] - LeBigCat
unfortunately that doesn't work either. - Thomas Crawford
I tested your query and it does seem to work. Could you append the exact parsing error? Also what Elasticsearch version are you currently using? - pat
Hi Pat, Made a stupid mistake. The query is working indeed. Thanks for testing - Thomas Crawford

1 Answers

2
votes

Your query looks good to me and ran in my test. It should work as is.

But in the interest of future readers, this is how multi-match queries work with elastic search.

GET /_search
{
  "query": {
    "multi_match" : {
      "query":      "Will Smith",
      "type":       "best_fields",
      "fields":     [ "first_name", "last_name" ],
      "operator":   "and" 
    }
  }
}

Note that this example from the elastic search documentation is identical in nature to your section of the code above:

...
                    'multi_match' => [
                      'query' => $request->get('search'),
                      'fields' => ['message', 'event.type'],
                      'operator' => 'AND',
                    ],
...

This is how multi-match queries are formed, and you did it.