使用grails插件将SQL查询转换为Java Elasticsearch Query

时间:2018-04-07 18:13:11

标签: sql elasticsearch grails elasticsearch-plugin

如何将以下SQL查询转换为Java Elasticsearch Query?

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    // Hide the navigation bar on the this view controller
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    // Show the navigation bar on other view controllers
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
}

我尝试了以下内容(不包括上面的OR子句)但失败了:

SELECT s.*
FROM supplier_detail_info sdi
JOIN supplier s ON sdi.supplier_id = s.id
JOIN supplier_detail sd ON sdi.supplier_detail_id = sd.id
WHERE (sdi.value = '70' AND sd.id = 1 ) OR (sdi.value = '46' and sd.id = 4);

这导致:

def query = QueryBuilders.boolQuery().
                    must(QueryBuilders.nestedQuery('supplierDetailInfos', QueryBuilders.matchQuery("supplierDetailInfos.value", '46')))
                    .must(QueryBuilders.nestedQuery('supplierDetailInfos.supplierDetail', QueryBuilders.matchQuery("supplierDetailInfos.supplierDetail.id", 4)))

我正在使用grails 2.3.7并拥有以下域名:

{
      "bool" : {
        "must" : [ {
          "nested" : {
            "query" : {
              "match" : {
                "supplierDetailInfos.value" : {
                  "query" : "46",
                  "type" : "boolean"
                }
              }
            },
            "path" : "supplierDetailInfos"
          }
        }, {
          "nested" : {
            "query" : {
              "match" : {
                "supplierDetailInfos.supplierDetail.id" : {
                  "query" : 4,
                  "type" : "boolean"
                }
              }
            },
            "path" : "supplierDetailInfos.supplierDetail"
          }
        } ]
      }
    }

我正在使用elasticsearch 2.3.5和弹性搜索插件“org.grails.plugins:elasticsearch:0.1.0”。

据我了解,

  

必须等同于AND

&安培;

  

应该等同于OR。

当supplier_detail id为4时,上述查询应仅返回supplier_detail_info的值为'46'的供应商。但它返回存在供应商详细信息且值为'46'的所有供应商。它只是忽略了查询的'和sd.id = 4'部分。另外,我无法弄清楚如何使用OR部分。

2 个答案:

答案 0 :(得分:0)

而不是bool查询尝试使用bool内部查询和两个必须子句的嵌套查询。另外我认为匹配查询应该是术语查询,因为它们看起来像关键字/长字段而不是文本字段,如果你想要OR,则必须使用should子句

{
   "query":{
      "nested":{
         "path":"supplierDetailInfos",
         "query":{
            "bool":{
               "must":[
                  {
                     "match":{
                        "supplierDetailInfos.value":"46"
                     }
                  },
                  {
                     "match":{
                        "supplierDetailInfos.supplierDetail.id":4
                     }
                  }
               ]
            }
         }
      }
   }
}

答案 1 :(得分:0)

感谢@ sramalingam24,我找到了解决问题的方法。 elasticsearch查询可以写成如下:

{
"query":{
  "nested":{
     "path":"supplierDetailInfos",
     "query":{
        "bool":{
           "must":[
              {
                 "match":{
                    "supplierDetailInfos.value":"46"
                 }
              },
              {
                 "query":{
                    "nested":{
                       "path":"supplierDetailInfos.supplierDetail",
                       "query":{
                          "bool":{
                             "must":[
                                {
                                   "match":{
                                      "supplierDetailInfos.supplierDetail.id":4
                                   }
                                },

                             ]
                          }
                       }
                    }
                 }
              }
           ]
        }
     }
  }
 }
}

可以使用QueryBuilders编写等效查询,如下所示:

def supplierDetailQuery = QueryBuilders.boolQuery()
def supplierDetailIdQuery = QueryBuilders.nestedQuery('supplierDetailInfos.supplierDetail',
                QueryBuilders.boolQuery()
                        .must(QueryBuilders.matchQuery("supplierDetailInfos.supplierDetail.id", id)))
def supplierDetailIdAndValueQuery = QueryBuilders.boolQuery()
                .must(QueryBuilders.matchQuery("supplierDetailInfos.value", value))
                .must(supplierDetailIdQuery)
supplierDetailQuery.must(QueryBuilders.nestedQuery('supplierDetailInfos',
                supplierDetailIdAndValueQuery))