• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

ElasticSearch API question

AndyB

Well-known member
#1
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:

AndyB

Well-known member
#2
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.jpg
 

Xon

Well-known member
#3
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
 

AndyB

Well-known member
#4
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.
 

Xon

Well-known member
#5
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.
 

AndyB

Well-known member
#6
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);
 

Marcus

Well-known member
#7
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?
 

AndyB

Well-known member
#8
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.