在Elasticsearch中匹配两个过滤条件

时间:2019-04-05 16:58:11

标签: elasticsearch elasticsearch-dsl

修改

我复制并粘贴了我在回复中发布的评论:

  

...查询正在正常工作。那个时候,当您感到无所适从,又不知道该怎么办时,我曾发布过这个问题。该错误既不在查询中也不在Elasticsearch中,这是因为我在Post中添加了新字段,而Lambda函数无法为新Posts(dynamic: false编制索引。最重要的是,我在Lambda日志上没有适当的CloudWatch警报。在分析Kibana日志后,我意识到了这一点。我以为创建帖子是因为它们出现在评论部分(主存储为Dynamo),但是这些帖子并未在Elasticsearch中建立索引。

原始问题

我在Elasticsearch中索引了成千上万的文档(帖子),我正在尝试做一个简单的查询:

SELECT *
FROM posts
WHERE comment LIKE '%comment%'
  AND created_at >= '2019-04-03'

我使用andbool查询尝试了不同的方法:

bool查询

{
    "from": 0,
    "size": 10,
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "comment": "comment"
                    }
                },
                {
                    "range": {
                        "created_at": {
                            "gte": "2019-04-03T00:00:00.000Z"
                        }
                    }
                }
            ]
        }
    }
}

结果

我得到一个空结果集:

{
    "took": 3,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 0,
        "max_score": null,
        "hits": []
    }
}

and查询

{
    "from": 0,
    "size": 10,
    "query": {
        "filtered": {
            "filter": {
                "and": {
                    "filters": [
                        {
                            "term": {
                                "comment": "comment"
                            }
                        },
                        {
                            "range": {
                                "updated_at": {
                                    "gte": "2019-04-03T00:00:00.000Z"
                                }
                            }
                        }
                    ]
                }
            }
        }
    }
}

结果

解析异常:

{
    "error": {
        "root_cause": [
            {
                "type": "parsing_exception",
                "reason": "no [query] registered for [filtered]",
                "line": 5,
                "col": 21
            }
        ],
        "type": "parsing_exception",
        "reason": "no [query] registered for [filtered]",
        "line": 5,
        "col": 21
    },
    "status": 400
}

分析器

我正在使用以下自定义分析器:

{
  analysis: {
    analyzer: {
      custom_analyzer: {
        tokenizer: 'custom_tokenizer',
        filter: 'lowercase'
      }
    },
    tokenizer: {
      custom_tokenizer: {
        type: 'ngram',
        min_gram: 2,
        max_gram: 16,
        token_chars: [
          'letter',
          'digit',
          'punctuation',
          'symbol'
        ]
      }
    },
  }
}

期望的结果

当我对match中的comment运行一个单独的查询,而对range中的created_at运行另一个查询时,我得到了它应该返回的内容:

comment中的文本进行搜索

{
    "from": 0,
    "size": 10,
    "query": {
        "bool": {
            "must": [
                {
                    "match": {
                        "comment": "comment"
                    }
                }
            ]
        }
    }
}

结果

{
    "took": 8,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 888,
        "max_score": 1.9128458,
        "hits": [...]
    }
}

range中按日期created_at搜索

{
    "from": 0,
    "size": 10,
    "query": {
        "bool": {
            "must": [
                {
                    "range": {
                        "created_at": {
                            "gte": "2019-04-03T00:00:00.000Z"
                        }
                    }
                }
            ]
        }
    }
}

结果

{
    "took": 7,
    "timed_out": false,
    "_shards": {
        "total": 5,
        "successful": 5,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": 19,
        "max_score": 1,
        "hits: [...]
    }
}

我敢肯定,在March 3rd字段中,在comment后面加上comment文本创建了帖子,我添加了包含该子字符串的注释的测试数据。

1 个答案:

答案 0 :(得分:0)

我无法直接发表评论或发送消息,但是您能否提供其他说明?

我尝试重新创建此问题,因为您的第一个搜索示例应该可以正常工作。为了确认这一点,我创建了一个简单的索引并添加了一些记录以测试您提供的不同查询:

POST demo/_doc
{
  "created_at": "2019-04-02T12:00:00.000Z",
  "comment": "contains comment"
}

POST demo/_doc
{
  "created_at": "2019-04-03T12:00:00.000Z",
  "comment": "contains another comment"
}

POST demo/_doc
{
  "created_at": "2019-04-03T12:00:00.000Z",
  "comment": "not what we are looking for"
}

请注意,我没有打扰自定义分析器,因为您的单个查询表明单个搜索正常工作,因此应该没有影响。

从那里开始,测试单个查询会产生预期的结果,而测试您提供的原始查询也会产生预期的结果:

查询:

GET demo/_search
{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "comment": "comment"
          }
        },
        {
          "range": {
            "created_at": {
              "gte": "2019-04-03T00:00:00.000Z"
            }
          }
        }
      ]
    }
  }
}

结果:

{
  "took" : 17,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : 1,
    "max_score" : 1.287682,
    "hits" : [
      {
        "_index" : "demo",
        "_type" : "_doc",
        "_id" : "-sxo72kBwpqm-gdssSYh",
        "_score" : 1.287682,
        "_source" : {
          "created_at" : "2019-04-03T12:00:00.000Z",
          "comment" : "contains another comment"
        }
      }
    ]
  }
}

唯一让我跳出来的可能性是,您在最后一条语句中指出,创建的帖子是“您在3月3日之后在评论字段中添加了评论文本”,但是查询实际上是在搜索包含评论文本的帖子在 April 3rd之后的评论字段中。但是,这很可能是错字。

或者,由于第二个查询仅返回19个匹配项(日期范围在created_at字段中),您能否查看它们,找到一个包含comment文本的注释字段,并且粘贴它还是它的摘录?