【问题标题】:elasticsearch multi_match with regexpelasticsearch multi_match 与正则表达式
【发布时间】:2017-07-20 19:09:47
【问题描述】:

我正在尝试重建我的弹性搜索查询,因为我发现我没有收到我正在寻找的所有文档。

所以,假设我有这样的文档:

{
  "id": 1234,
  "mail_id": 5,
  "sender": "john smith",
  "email": "johnsmith@gmail.com",
  "subject": "somesubject",
  "txt": "abcdefgh\r\n",
  "html": "<div dir=\"ltr\">abcdefgh</div>\r\n",
  "date": "2017-07-020 10:00:00"
}

我有几百万这样的文档,现在我正试图通过这样的查询来搜索一些:

{
  "sort": [
    {
      "date": {
        "order": "desc"
      }
    }
  ],
  "query": {
    "bool": {
      "minimum_should_match": "100%",
      "should": [
        {
          "multi_match": {
            "type": "cross_fields",
            "query": "abcdefgh johnsmith john smith",
            "operator": "and",
            "fields": [
              "email.full",
              "sender",
              "subject",
              "txt",
              "html"
            ]
          }
        }
      ],
      "must": [
        {
          "ids": {
            "values": [
              "1234"
            ]
          }
        },
        {
          "term": {
            "mail_id": 5
          }
        }
      ]
    }
  }
}

对于这样的查询,一切都很好,但是当我想通过查询“gmail”或“c​​om”来查找文档时,它就不起作用了。

"query": "abcdefgh johnsmith john smith gmail"
"query": "abcdefgh johnsmith john smith com"

只有当我搜索“gmail.com”时它才会起作用 “查询”:“abcdefgh johnsmith john smith gmail.com”

所以...我试图附加分析器

...
"type": "cross_fields",
"query": "abcdefgh johnsmith john smith",
"operator": "and",
"analyzer": "simple",
...

根本没有帮助。我能够找到此文档的唯一方法是定义正则表达式,例如:

"minimum_should_match": 1,
"should": [
  {
    "multi_match": {
      "type": "cross_fields",
      "query": "fdsfs wukamil kam wuj gmail.com",
      "operator": "and",
      "fields": [
        "email.full",
        "sender",
        "subject",
        "txt",
        "html"
      ]
    }
  },
  {
    "regexp": {
      "email.full": ".*gmail.*"
    }
  }
],

但在这种方法中,我必须将(查询 * 字段)正则表达式对象添加到我的 json 中,所以我认为这不是最好的解决方案。我也知道通配符,但它会像正则表达式一样混乱。

如果有人遇到这样的问题并知道解决方案,我将非常感谢您的帮助:)

【问题讨论】:

  • 你能显示你的email字段映射在ES内部吗?
  • email.full 只是 {"type" : "text"}

标签: elasticsearch


【解决方案1】:

如果您通过标准分析器运行搜索词,您可以看到 johnsmith@gmail.com 被分解为哪些标记。您可以使用以下 URL 直接在浏览器中执行此操作:

https://<your_site>:<es_port>/_analyze/?analyzer=standard&text=johnsmith@gmail.com

这将表明电子邮件被分解为以下标记:

{

    "tokens": [
        {
            "token": "johnsmith",
            "start_offset": 0,
            "end_offset": 9,
            "type": "<ALPHANUM>",
            "position": 1
        },
        {
            "token": "gmail.com",
            "start_offset": 10,
            "end_offset": 19,
            "type": "<ALPHANUM>",
            "position": 2
        }
    ]

}

所以这表明您不能只使用gmail 进行搜索,但可以使用gmail.com。要在点上拆分文本,您可以更新映射以使用 Simple Analyzer,它表示:

只要遇到不是字母的字符,简单的分析器就会将文本分解为术语。所有术语都小写。

我们可以通过更新我们之前的 URL 来使用下面的简单分析器来展示这项工作:

https://<your_site>:<es_port>/_analyze/?analyzer=simple&text=johnsmith@gmail.com

返回:

{

    "tokens": [
        {
            "token": "johnsmith",
            "start_offset": 0,
            "end_offset": 9,
            "type": "word",
            "position": 1
        },
        {
            "token": "gmail",
            "start_offset": 10,
            "end_offset": 15,
            "type": "word",
            "position": 2
        },
        {
            "token": "com",
            "start_offset": 16,
            "end_offset": 19,
            "type": "word",
            "position": 3
        }
    ]

}

此分析器可能不适合这项工作,因为它会忽略任何非字母值,但您可以使用分析器和标记器,直到您获得所需。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 2011-08-06
    • 1970-01-01
    • 1970-01-01
    • 2014-10-08
    • 2023-03-13
    • 2019-01-31
    相关资源
    最近更新 更多