2014-08-28 58 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