2

I have an Elastic Search query as:

{
  "query": {
    "bool": {
      "must": [ 
       {
       "match": {"title": "accountant"}
       },
       {
          "nested": {
            "path": "schools", 
            "query": {
              "bool": {
                "must": [ 
                  { "match": { "schools.school_name": "Duke University" }}
                ]
        }}}}
      ]
}}}

I'm using Elastica library of php and I want to convert this raw query into Elastica. I know I can run raw query from Elastica, but I would prefer using Elastica classes. I have tried this and this. But none of them works. Here is the simplified version of my current code:

$schoolsTermFilter = new \Elastica\Filter\Term(['schools.school_name' => "Duke University"]);
$schoolsBoolFilter = new \Elastica\Filter\Bool();
$schoolsBoolFilter->addMust($schoolsTermFilter);

$nestedFilter = new \Elastica\Filter\Nested();
$nestedFilter->setPath("schools");
$nestedFilter->setFilter($schoolsBoolFilter);

$boolFilter = new \Elastica\Filter\Bool();
$boolFilter->addMust($nestedFilter);

$query->setPostFilter($boolFilter);

However, this returns empty results. The raw query does return results, so I know I should get something. Can anybody help me in this? Thanks

Community
  • 1
  • 1
Ibrahim
  • 837
  • 2
  • 13
  • 24

2 Answers2

6

This is the QueryBuilder version (>= v1.4.2.0):

$qb = new \Elastica\QueryBuilder();

$query = new \Elastica\Query(
    $qb->query()->bool()
        ->addMust($qb->query()->match(
            'title',
            'accountant'
        ))
        ->addMust($qb->query()->nested()
            ->setPath('schools')
            ->setQuery(
                $qb->query()->bool()
                    ->addMust($qb->query()->match(
                        'schools.school_name',
                        'Duke University'
                    ))
            )
        )
);
webdev
  • 61
  • 1
4

Here is a 1:1 translation to Elastica for your query:

$query = new \Elastica\Query();

$matchQuery = new \Elastica\Query\Match();
$matchQuery->setField("title", "accountant");

$schoolsTermQuery = new \Elastica\Query\Match();
$schoolsTermQuery->setField("schools.school_name", "Duke University");
$schoolsBoolQuery = new \Elastica\Query\Bool();
$schoolsBoolQuery->addMust($schoolsTermQuery);

$nestedQuery = new \Elastica\Query\Nested();
$nestedQuery->setPath("schools");
$nestedQuery->setQuery($schoolsBoolQuery);

$boolQuery = new \Elastica\Query\Bool();
$boolQuery->addMust($matchQuery);
$boolQuery->addMust($nestedQuery);

$query->setQuery($boolQuery);

print_r(json_encode($query->toArray()));

The Elasticsearch query which you have pasted does not contain filters, only queries. So, the Elastica translation should not use objects from \Elastica\Filter but from \Elastica\Query instead. Also, if you want to verify the query before using it in Elasticsearch, you can print it with $query->toArray().

VolenD
  • 3,592
  • 18
  • 23