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

ElasticSearch API question

Discussion in 'XenForo Development Discussions' started by AndyB, Oct 20, 2015.

  1. AndyB

    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: Oct 20, 2015
    Marcus likes this.
  2. AndyB

    AndyB Well-Known Member

    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
     
  3. Xon

    Xon Well-Known Member

    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
     
    Marcus likes this.
  4. AndyB

    AndyB Well-Known Member

    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.
     
  5. Xon

    Xon Well-Known Member

    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.
     
  6. AndyB

    AndyB Well-Known Member

    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 (
                        
    => array(
                            
    'term' => array(
                                
    'thread.node' => $currentNodeId
                            
    )
                        ),
                        
    => array(
                            
    'range' => array(
                                
    'thread.date' => array(
                                    
    'gte' => $gte
                                
    )
                            )
                        )
                    ),
                    
    'must_not' => array(
                        
    'term' => array(
                            
    'thread.discussion_id' => $currentThreadId
                        
    )
                    )
                )
            )
        )
    );

    $results XenES_Api::search($indexName$dsl);
     
    Xon likes this.
  7. Marcus

    Marcus Well-Known Member

    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?
     
  8. AndyB

    AndyB Well-Known Member

    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.
     
    Marcus likes this.

Share This Page