Scott C Wilson
Scott C Wilson

Reputation: 20046

PHP ElasticSearch compound query with has_child

When I query Elasticsearch for products from a specific manufacturer, this works:

  $params = ['index' => 'products',
     'type' => 'product',
     'body' => ['query' =>
        ['match' => ['manufacturers_id' => $query],],
     ],
  ];

But when I also want to add on a condition that the product comes in color Silver, which I have added as a child record to the product record, I get a syntax error:

 $params = ['index' => 'products',
     'type' => 'product',
     'body' => ['query' =>
        ['match' => ['manufacturers_id' => $query],],
        ['query' =>
          ['has_child' =>
            ['type' => 'attributes',
            ['query' =>
              ['color' => 'Silver'],],
            ],
            ],
        ],
     ],
  ];

The error is

{
    "error": {
        "col": 49,
        "line": 1,
        "reason": "Unknown key for a START_OBJECT in [0].",
        "root_cause": [
            {
                "col": 49,
                "line": 1,
                "reason": "Unknown key for a START_OBJECT in [0].",
                "type": "parsing_exception"
            }
        ],
        "type": "parsing_exception"
    },
    "status": 400
}

Also tried

  $params = ['index' => 'products',
     'type' => 'product',
     'body' => ["query"=> [
                    "match"=> [
                        "manufacturers_id"=> [11]
                    ],
                    "has_child"=> [
                        "type"=> "attributes",
                        "query"=> [
                            "match"=> [
                                "color"=> "silver"
                            ],
                        ],
                    ],
                ],
     ],
  ];

I get "Can't get text on a START_ARRAY at 1:39."

Upvotes: 0

Views: 129

Answers (2)

Scott C Wilson
Scott C Wilson

Reputation: 20046

Finally got this to work. Big thanks to @pawle for his suggestion of Sense, which really helped.

  $params = ['index' => 'products',
     'type' => 'product',
     'body' =>
        [
           "query" => [
              "bool" => [
                 "must" => [[
                    "has_child" => [
                       "type" => "attributes",
                       "query" => [
                          "match" => [
                             "attributes_value" => "silver"
                          ]
                       ]
                    ]
                 ],
                    [
                       "match" => [
                          "manufacturers_id" => 4
                       ]
                    ]
                 ]
              ]
           ]
        ],
  ];

Upvotes: 0

pawle
pawle

Reputation: 21

Try this:

"query"=> [
    "match"=> [
        "manufacturers_id"=> [1,2,3]
    ],
    "has_child"=> [
        "type"=> "attributes",
        "query"=> [
            "match"=> [
                "color"=> "silver"
            ]
        ]
    ]
]

I also recommend Sense, it's a plugin for Chrome browser which helps writing ES queries. See the screenshot

Upvotes: 1

Related Questions