如何搜索包含子字符串的文档

时间:2019-08-07 10:53:22

标签: elasticsearch querydsl

我具有以下(部分)映射的文档:

  "message": {
    "type": "text",
    "fields": {
      "keyword": {
        "type": "keyword",
        "ignore_above": 256
      }
    }
  },

我正在尝试通过以下DSL查询来查询包含"success":"0"的文档:

{
  "query": {
    "bool": {
      "must": {
        "regexp": {
          "message": ".*\"success\".*0.*"
        }
      }
    }
  }
}

但是我没有得到任何结果,但是如果我执行以下DSL:

{
  "query": {
    "bool": {
      "must": {
        "regexp": {
          "message": ".*\"success\""
        }
      }
    }
  }
}

我退了一些文件!即

{"data":"[{\"appVersion\":\"1.1.1\",\"installationId\":\"any-ubst-id\",\"platform\":\"aaa\",\"brand\":\"Dalvik\",\"screenSize\":\"xhdpi\"}]","executionTime":"0","flags":"0","method":"aaa","service":"myService","success":"0","type":"aservice","version":"1"}

我的查询出了什么问题?

1 个答案:

答案 0 :(得分:1)

文本字段#include <stdio.h> struct fxdata { int foo; }; int function(int n, struct fxdata *p) { p->foo += n; return p->foo; } int main(void) { struct fxdata f1 = {0}; struct fxdata f2 = {0}; function(10, &f1); // returns 10 function(-4, &f2); // returns -4 printf("%d, %d\n", function(1, &f1), function(-1, &f2)); } 使用标准分析器来对输入字符串进行标记化并将其转换为标记。

如果我们使用标准分析器分析字符串message,我们将获得这些令牌

"success":"0"

因此您可以看到冒号双引号等已删除。而且由于正则表达式查询应用于每个令牌,因此它与您的查询不匹配。

但是如果我们使用具有字段类型关键字的{ "tokens": [ { "token": "success", "start_offset": 2, "end_offset": 9, "type": "<ALPHANUM>", "position": 0 }, { "token": "0", "start_offset": 12, "end_offset": 13, "type": "<NUM>", "position": 1 } ] } 。不会对其进行分析,因此请按原样保留字符串。

message.keyword

因此,如果我们使用以下查询,它应该可以工作

{
  "tokens": [
    {
      "token": """ "success":"0" """,
      "start_offset": 0,
      "end_offset": 15,
      "type": "word",
      "position": 0
    }
  ]
}

但是另一个问题是您将{ "query": { "regexp": { "message.keyword": """.*"success".*0.*""" } } } 字段设置设置为message.keyword,因此该字段将忽略任何长度超过256个字符的字符串。