2011-08-25 85 views
15

我一直在使用最近幾個月的ElasticSearch,但是當我必須傳遞一個複雜的查詢時仍然很複雜。如何將ElasticSearch查詢參數(DSL查詢)用於多種類型?

我想運行,這將有搜索多個「類型」查詢每種類型都有與自己的「過濾器」進行搜索,但需要有組合拳「搜索結果」

例如:

我需要搜索作爲我的朋友的「用戶類型」文檔,同時根據提供的關鍵字搜索我喜歡的「對象類型」文檔。

OR

具有查詢兩者 「AND」 和 「NOT」 子句

實施例的查詢:

$options['query'] = array(
     'query' => array(
      'filtered' => array(
       'query' => array(
        'query_string' => array(
         'default_field' => 'name', 
         'query' => $this->search_term . '*', 
        ), 
       ), 
       'filter' => array(
        'and' => array(
         array(
          'term' => array(
           'access_id' => 2, 
          ), 
         ), 
        ), 

        'not' => array(
         array(
          'term' => array(
           'follower' => 32, 
          ), 
         ), 

         array(
          'term' => array(
           'fan' => 36, 
          ), 
         ), 
        ), 
       ), 
      ), 
     ), 
    ); 

作爲此查詢是指,以搜尋與access_id = 2的用戶,但一定不能有追隨者的ID 32和ID 36的粉絲

但這是行不通的。

編輯:修改後的查詢

{ 
    "query": { 
    "filtered": { 
     "filter": { 
     "and": [ 
      { 
      "not": { 
       "filter": { 
       "and": [ 
        { 
        "query": { 
         "query_string": { 
         "default_field": "fan", 
         "query": "*510*" 
         } 
        } 
        }, 
        { 
        "query": { 
         "query_string": { 
         "default_field": "follower", 
         "query": "*510*" 
         } 
        } 
        } 
       ] 
       } 
      } 
      }, 
      { 
      "term": { 
       "access_id": 2 
      } 
      } 
     ] 
     }, 
     "query": { 
     "field": { 
      "name": "xyz*" 
     } 
     } 
    } 
    } 
} 

現在正在運行此查詢後,我得到兩個結果,一個與跟隨:「34518」 &球迷:「510」和第二風扇:「34」,但不是它應該只是結果中的第二個。

任何想法?

回答

14

你可能想看看,我這個月做了演示,解釋的查詢DSL如何工作的基礎知識的幻燈片:

Terms of endearment - the ElasticSearch Query DSL explained

與您的查詢的問題是,您的過濾器嵌套不正確。該andnot過濾器是在同一水平,但not過濾器應該是and下:

curl -XGET 'http://127.0.0.1:9200/_all/_search?pretty=1' -d ' 
{ 
    "query" : { 
     "filtered" : { 
     "filter" : { 
      "and" : [ 
       { 
        "not" : { 
        "filter" : { 
         "and" : [ 
          { 
           "term" : { 
           "fan" : 36 
           } 
          }, 
          { 
           "term" : { 
           "follower" : 32 
           } 
          } 
         ] 
        } 
        } 
       }, 
       { 
        "term" : { 
        "access_id" : 2 
        } 
       } 
      ] 
     }, 
     "query" : { 
      "field" : { 
       "name" : "keywords to search" 
      } 
     } 
     } 
    } 
} 
' 
+0

「不」過濾器總是在「和」過濾器下,或者只是在這種情況下 –

+0

Hi @DrTech,我剛剛編輯了問題,請檢查。 –

+1

您編輯的問題引入了其他問題。我建議你看看我鏈接到的演示文稿 - 它解釋了術語和文本之間的區別,以及在哪裏使用哪些類型的查詢或過濾器。 – DrTech

3

我只是用「BOOL」

{ 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "term": { 
      "access_id": 2 
      } 
     }, 
     { 
      "wildcard": { 
      "name": "xyz*" 
      } 
     } 
     ], 
     "must_not": [ 
     { 
      "wildcard": { 
      "follower": "*510*" 
      } 
     }, 
     { 
      "wildcard": { 
      "fan": "*510*" 
      } 
     } 
     ] 
    } 
    } 
} 

它給出了正確的答案嘗試過。

但我不確定它是否應該這樣使用?

+2

這會工作,但效率非常低。通配符子句必須加載所有術語,找到匹配的所有術語,然後重寫查詢以包含所有這些術語。這真的會炸燬。在索引時間正確分析數據要好得多,以便您可以將您的值分解爲單獨的術語,您可以單獨匹配。您可能需要查看使用ngram分析器,但這取決於您的數據。看看這個線程的例子http://elasticsearch-users.115913.n3.nabble.com/help-needed-with-the-query-tt3177477.html#a3178856 – DrTech

+1

謝謝@DrTech,這是非常好的解釋。 +1。我真的會說你應該寫一個關於ElasticSearch的完整教程,因爲沒有人做過它:)謝謝 –

相關問題