2014-08-28 42 views
6

我有以下格式幾個JSON文件: -OR和AND運算

_source: { 
      userId: "A1A1", 
      customerId: "C1", 
      component: "comp_1", 
      timestamp: 1408986553, 
    } 

我想查詢基於以下文件: -

((userId == currentUserId) OR (customerId== currentCustomerId) OR (currentRole ==ADMIN)) AND component= currentComponent) 

我嘗試使用SearchSourceBuilder和QueryBuilders.matchQuery,但我無法使用AND和OR運算符進行多個子查詢。

SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder(); 
searchSourceBuilder.query(QueryBuilders.matchQuery("userId",userId)).sort("timestamp", SortOrder.DESC).size(count); 

我們如何使用OR和AND運算符來查詢elasticsearch?

回答

24

我認爲在這種情況下,Bool query是最好的拍攝。

喜歡的東西:

{ 
    "bool" : { 
     "must" : { "term" : { "component" : "comp_1" } }, 
     "should" : [ 
      { "term" : { "userId" : "A1A1" } }, 
      { "term" : { "customerId" : "C1" } }, 
      { "term" : { "currentRole" : "ADMIN" } } 
     ], 
     "minimum_should_match" : 1 
    } 
} 

在Java中其中給出:

QueryBuilder qb = QueryBuilders 
    .boolQuery() 
    .must(termQuery("component", currentComponent)) 
    .should(termQuery("userId", currentUserId)) 
    .should(termQuery("customerId", currentCustomerId)) 
    .should(termQuery("currentRole", ADMIN)) 
    .minimumShouldMatch("1"); // or .minimumNumberShouldMatch(1) 

must部分是AND秒,should部分都或多或少OR S,不同之處在於你可以指定一個最短匹配的should的號碼(使用minimum_should_match),這個最低默認爲1,我認爲(但你可以將其設置爲0,這意味着文件不匹配should條件也會被返回)。

如果你想要做更復雜的查詢涉及嵌套AND S和OR S,內部mustshould部分乾脆窩等布爾查詢。

此外,當您正在查找確切的值(ID等)時,也許您可​​以使用term queries instead of match queries,這可以讓您省去分析階段(如果這些字段是完全分析的,這對於IDS)。如果他們被分析,你仍然可以這樣做,但前提是你確切知道你的條款是如何存儲的(standard analyzer stores them lower cased for instance)。

+0

'.minimumShouldMatch'需要一個字符串僅作爲參數,對不對? – BairDev 2015-03-30 13:24:22

+0

@malte你說得對。在這種情況下,它應該是'minimumNumberShouldMatch'和'int',或者'minimumShouldMatch'和'string'。糾正。 – 2015-03-30 13:31:03

+0

我認爲這應該是被接受的答案。 +1 – NickGreen 2017-02-07 11:09:45

2

如果您使用query_string query,則您的AND和OR將被Lucene庫解釋爲這樣。

這可以讓你搜索

(currentUserId OR currentCustomerId) AND currentComponent 

例如。默認情況下,這些值將在所有字段中搜索。

+0

但是像QueryBuilders.queryString(「(userId:」+ currentUserId +「或customerId:」+ currentCustomerId +「或currentRole:」+ ADMIN +「)AND組件:」+ currentComponent +「)」)'應該按照預期的方式工作。從ElasticSearch文檔的鏈接頁面 – 2014-08-29 09:08:07

+0

:「爲查詢詞的默認字段,如果沒有指定前綴字段默認爲index.query.default_field索引設置,這反過來又默認爲_All。」顯然,ElasticSearch會在索引時間添加_all字段,然後我們可以應用Lucene語法。 – 2014-08-29 09:09:24