Elasticsearch DSL或查询格式

时间:2018-09-19 08:57:54

标签: python-3.x elasticsearch elasticsearch-dsl-py

我有多个文档的索引。这些文档包含以下字段:

  • 名称
  • adhar_number
  • pan_number
  • acc_number

我想创建一个elasticsearch dsl查询。对于此查询,有两个输入可用,例如adhar_number和pan_number。此查询应与此上的 OR条件相符。

示例:如果一个文档仅包含提供的adhar_number,那么我也希望该文档。

我有一本字典,其内容如下(my_dict):

{
  "adhar_number": "123456789012",
  "pan_number": "BGPPG4315B"
}

我尝试如下:

from elasticsearch import Elasticsearch
from elasticsearch_dsl import Search

es = Elasticsearch([{'host': 'localhost', 'port': 9200}])
s = Search(using=es, index="my_index")
for key, value in my_dict.items():
   s = s.query("match", **{key:value})

print(s.to_dict())
response = s.execute()
print(response.to_dict())

它创建以下查询:

{
  'query': {
    'bool': {
      'must': [
        {
          'match': {
            'adhar_number': '123456789012'
          }
        },
        {
          'match': {
            'pan_number': 'BGPPG4315B'
          }
        }
      ]
    }
  }
}

以上代码为我提供的结果是 AND条件,而不是 OR条件

请向我建议包含OR条件的好建议。

2 个答案:

答案 0 :(得分:0)

要修复ES查询本身,您所需要做的就是使用“应该”而不是“必须”:

private void detectInVisionImage(
        FirebaseVisionImage image,
        final FrameMetadata metadata) {

    detectInImage(image)
            .addOnSuccessListener(
                    new OnSuccessListener<T>() {
                        @Override
                        public void onSuccess(final T results) {
                            new Handler().postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    shouldThrottle.set(false);
                                }
                            },1000);


                            VisionProcessorBase.this.onSuccess(results, metadata);

                        }
                    })
            .addOnFailureListener(
                    new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {
                            new Handler().postDelayed(new Runnable() {
                                @Override
                                public void run() {
                                    shouldThrottle.set(false);
                                }
                            },1000);
                            VisionProcessorBase.this.onFailure(e);
                        }
                    });
    // Begin throttling until this frame of input has been processed, either in onSuccess or
    // onFailure.
    shouldThrottle.set(true);



}

要在python中实现此目的,请参见the docs中的以下示例。默认逻辑为AND,但是您可以将其覆盖为OR,如下所示。

  

查询组合可以使用逻辑组合查询对象   运算符:

{
  'query': {
    'bool': {
      'should': [
        {
          'match': {
            'adhar_number': '123456789012'
          }
        },
        {
          'match': {
            'pan_number': 'BGPPG4315B'
          }
        }
      ]
    }
  }
}
     

当您多次调用.query()方法时,&运算符将在内部使用:

Q("match", title='python') | Q("match", title='django')
# {"bool": {"should": [...]}}

Q("match", title='python') & Q("match", title='django')
# {"bool": {"must": [...]}}

~Q("match", title="python")
# {"bool": {"must_not": [...]}} 
     

如果要精确控制查询表单,请使用Q快捷方式直接构建组合   查询:

s = s.query().query() print(s.to_dict())
# {"query": {"bool": {...}}}

所以你想要类似的东西

q = Q('bool',
    must=[Q('match', title='python')],
    should=[Q(...), Q(...)],
    minimum_should_match=1 ) s = Search().query(q)

答案 1 :(得分:0)

您也可以使用@ ifo20提到的should。请注意,您很可能还希望定义minimum_should_match参数:

您可以使用minimum_should_match参数指定返回的文档必须匹配的应当子句的数量或百分比。

如果布尔查询包含至少一个should子句,并且没有must或filter子句,则默认值为1。否则,默认值为0。

{
  'query': {
    'bool': {
      'should': [
        {
          'match': {
            'adhar_number': '123456789012'
          }
        },
        {
          'match': {
            'pan_number': 'BGPPG4315B'
          }
        }
      ],
      "minimum_should_match" : 1
    }
  }
}

还请注意,should子句有助于最终得分。我不知道如何避免这种情况,但您可能不希望它成为OR逻辑的一​​部分。