ElasticSearch API question

AndyB

Well-known member
Hello,

I'm trying to use the following ElasticSearch API code. For simple queries the ElasticSearch API is working very good, however the following query does not work (returns empty results) when I add the 'range' portion of the code:

PHP:
$dsl['query'] = array(
    'filtered' => array(
        'query' => array(
            'match' => array(
                'thread.title' => array(
                    'query' => $threadTitle,
                    'operator' => 'or'
                )
            )                                                       
        ),                       
        'filter' => array(
            'bool' => array(
                'must' => array(
                    'term' => array(
                        'thread.node' => $currentNodeId
                    ),
                    'range' => array(
                        'thread.date' => array(
                            'gt' => $gt
                        )
                    )                                                                                                                           
                ),               
                'must_not' => array(
                    'term' => array(
                        'thread.discussion_id' => $currentThreadId
                    )
                )                           
            )                                                       
        )
    )
);
$results = XenES_Api::search($indexName, $dsl);

The following code using cURL works perfect:

PHP:
$data_string = '{
    "from" : 0, "size" : "' . $maximumResults . '",
    "query" : {
        "filtered" : {
            "query" : {
                "match" : {
                    "thread.title" : {
                        "query" : "' . $threadTitle . '",
                        "operator" : "or"
                    }
                }
            },
            "filter" : {
                "bool" : {
                    "must" : [
                    {
                        "term" : {
                            "thread.node" : "' . $currentNodeId . '"
                        }
                    },
                    {
                        "range" : {
                            "thread.date" : {
                                "gt" : "' . $gt . '"
                            }
                        }
                    }
                    ],
                    "must_not" : {
                        "term" : {
                            "thread.discussion_id" : "' . $currentThreadId . '"
                        }
                    }
                }
            }
        }
    }
}';

The only difference I can see is the cURL code above uses the square brackets around the 'must' portion of the code.

Any help greatly appreciated.
 
Last edited:
Here's an image with two red arrows. What I need to do is duplicate the two square brackets with the ElasticSearch API code, is this possible?

pic001.webp
 
The only difference I can see is the cURL code above uses the square brackets around the 'must' portion of the code.

Any help greatly appreciated.
Add another "array()" inside the "must" clause .

ie
PHP:
$dsl['query'] = array(
    'filtered' => array(
        'query' => array(
            'match' => array(
                'thread.title' => array(
                    'query' => $threadTitle,
                    'operator' => 'or'
                )
            )                                                    
        ),                    
        'filter' => array(
            'bool' => array(
                'must' => array(array(
                    'term' => array(
                        'thread.node' => $currentNodeId
                    ),
                    'range' => array(
                        'thread.date' => array(
                            'gt' => $gt
                        )
                    )                                                                                                                        
                )),            
                'must_not' => array(
                    'term' => array(
                        'thread.discussion_id' => $currentThreadId
                    )
                )                        
            )                                                    
        )
    )
);

Elastic Search's query format is amazingly verbose, and is very confusing when mixed with php arrays
 
Hi Xon,

Thank you kindly for looking into this problem. I have tried and tried again your suggestion, but unfortunately it doesn't work, I get back zero results when the 'range' part of the query is added no matter what I try. Using the same code but in cURL format works perfectly, using the ElasticSearch API code does not work.
 
Brute force solution time.

Take yourworking json and run it through the php function"json_decode" it into a variable. And then var_export() that variable and you should get a chunk of valid php code.

php sadly makes it hard todo integer based arrays vs associative arrays and this matters for json.
 
Thank you, Xon.

This code now works perfectly.

PHP:
$dsl['query'] = array(
    'filtered' => array(
        'query' => array(
            'match' => array(
                'thread.title' => array(
                    'query' => $threadTitle,
                    'operator' => 'or'
                )
            )
        ),
        'filter' => 	array(
            'bool' => array(
                'must' => array (
                    0 => array(
                        'term' => array(
                            'thread.node' => $currentNodeId
                        )
                    ),
                    1 => array(
                        'range' => array(
                            'thread.date' => array(
                                'gte' => $gte
                            )
                        )
                    )
                ),
                'must_not' => array(
                    'term' => array(
                        'thread.discussion_id' => $currentThreadId
                    )
                )
            )
        )
    )
);

$results = XenES_Api::search($indexName, $dsl);
 
  • Like
Reactions: Xon
It's absolutely amazing how easy the elasticsearch query looks. Just out of interest, do you have to add the array keys (0 =>, 1 =>) or would it also work without?
 
do you have to add the array keys (0 =>, 1 =>) or would it also work without?

Unfortunately it appears the API only accepts the (0 =>, 1 =>) keys added manually. I have another situation where I have to dynamically add the same type of keys through a variable and it appears to be impossible to do. So for simple queries the API works fine, but not those queries which require the (0 =>, 1 =>) to be added through a variable.
 
Top Bottom