【问题标题】:python elasticsearch: how to query a string on all fieldspython elasticsearch:如何查询所有字段的字符串
【发布时间】:2019-04-28 09:03:17
【问题描述】:

我有以下运行良好的 python 代码,按预期为我带来了 50 个结果:

elastic = settings.ELASTIC
indexes = u'nginx-access-2769z-2018.11.26.16'
filter_by_client = [
    {'match_phrase': {'client_id': '2769z'}},
]
range_for_search = {
    'gte': str(1543248611),
    'lte': str(1543249511),
    'format': 'epoch_second',
}
query_body = {
    'from': 0,
    'size': 50,
    'query': {
        'bool': {
            'must': filter_by_client,
            'filter': {'range': {'@timestamp': range_for_search}},
        },
    }
}
search_result = elastic.search(index=indexes, body=query_body)
results = [result['_source'] for result in search_result['hits']['hits']]

如果我现在添加另一个过滤器,例如

...
filter_by_client = [
    {'match_phrase': {'client_id': '2769z'}},
    {'match': {'remote_address': '181.220.174.189'}}
]
...

它也可以正常工作!将其缩小到 5 个结果。

我的问题是:如何在 所有字段 上查询该字符串?如果该字符串位于字段的开头/结尾,如果它是大写,如果该字段实际上是整数/浮点数而不是字符串,对我来说并不重要,...

已经尝试过像这样使用“_all”关键字

...
filter_by_client = [
    {'match_phrase': {'client_id': '2769z'}},
    {'match': {'_all': '181.220.174.189'}}
]
...

但它给了我 0 个结果。试图重现发生在 Kibana 界面上的相同行为。

【问题讨论】:

  • 如elasticsearch文档中提到的_alldeprecated。改用copy_to 并查询使用copy_to 参数索引的自定义字段。

标签: python elasticsearch elastic-stack elasticsearch-py


【解决方案1】:

Nishant 提到的是使用 copy_to 字段的最佳解决方案,但是如果您无法控制更改映射,那么您可以尝试查看以下任何方法是否有帮助。

使用查询字符串查询

您可以使用Query String Query,您的查询如下:

...
filter_by_client = [
    {'match_phrase': {'client_id': '2769z'}},
    {'query_string': {'query': '181.220.174.189'}}
]
... 

一个重要的注意事项是query_string 默认搜索所有字段。我提到的链接如下:

如果没有指定前缀字段,则查询词的默认字段。 默认为 index.query.default_field 索引设置,在 将默认设置为 *。 * 提取映射中的所有字段 符合条件的术语查询和过滤元数据字段。

我之所以提到这一点,是因为我希望您在决定使用 query_string 之前了解使用 query_string 与简单匹配 Match vs Query-String 的区别。

查询的匹配族不经过“查询解析” 过程。它不支持字段名称前缀、通配符、 或其他“高级”功能。因此,它失败的机会 非常小/不存在,它提供了出色的行为 当只是分析和运行该文本作为查询行为时 (这通常是文本搜索框所做的)。此外,该 phrase_prefix 类型可以提供一个很好的“当你输入”的行为 自动加载搜索结果。

使用多重匹配

如果您不想更改映射,则以下另一种可能的解决方案使用multi-match 查询

...
filter_by_client = [
    {'match_phrase': {'client_id': '2769z'}},
    {'multi_match': {'query': '181.220.174.189', 'fields': ['url', 'field_2']}}
]
...

了解如何在查询时明确提及要考虑的字段。但请务必彻底验证/测试它。

如果这有帮助,请告诉我!

【讨论】:

  • 我会研究使用copy_to 的这个选项,但要知道我会接受你的建议。谢谢!!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-26
  • 2020-08-21
相关资源
最近更新 更多