【问题标题】:Elastic search with space带空间的弹性搜索
【发布时间】:2015-09-09 06:02:25
【问题描述】:

我有一个 Elasticsearch 设置,它允许用户搜索索引作为通配符。

array:3 [
 "index" => "users"
 "type" => "user"
 "body" => array:4 [
 "from" => 0
 "size" => 25
 "sort" => array:1 [
  1 => array:1 [
    "order" => "asc"
  ]
]
"query" => array:1 [
  "bool" => array:1 [
    "should" => array:1 [
      0 => array:1 [
        0 => array:1 [
          "wildcard" => array:1 [
            "full_name" => "john doe"
          ]
        ]
      ]
    ]
  ]
]
]
]

当我将此数组传递给搜索函数时,它返回一个空数组。但是有一个与“John Doe”相关的文档,当我运行 "full_name" => "john" 时,搜索会返回该文档。

我觉得问题出在空间上。

{
"users": {
"user": {
  "properties": {

    "address": {
      "type": "string"
    },
    "full_name": {
      "type": "string"
    },
    "industry_name": {
      "type": "string"
    }
  }
}

} }

【问题讨论】:

标签: php elasticsearch


【解决方案1】:

假设字段full_name被elasticsearch分析。

您的问题是wildcard query 不分析搜索字符串

匹配具有与通配符表达式匹配的字段的文档(不是 分析)。

在您的情况下,这意味着弹性搜索将 johndoe 标记存储在倒排索引中,但通配符查询正在搜索 john doe 标记,但它失败了。

你可以做些什么:

  1. 更改索引映射,因此不再分析full_name 字段。 注意:您必须搜索 John Doe 才能获得匹配,因为 未分析值,因此 john doe 将不匹配。
  2. 您可以改进第一个解决方案,只需离开full_name 分析,但使用自定义分析器(通配符,小写)。它会 允许您搜索文本john doeJohn Doe

    {
        "settings" : {
            "index" : {
                "analysis" : {
                    "analyzer" : {
                        "lowercase_analyzer" : {
                            "tokenizer" : "keyword",
                            "filter" : [
                                "lowercase"
                            ],
                            "type" : "custom"
                        }
                    }
                }
            }
        },
        "mappings" : {
            "user" : {
                "properties" : {
                    "id" : {
                        "type" : "integer"
                    },
                    "fullName" : {
                        "analyzer" : "lowercase_analyzer",
                        "type" : "string"
                    }
                }
            }
        }
    }
    
  3. 您可以利用multi field,并搜索原始 字段。

    "full_name.raw" => "John Doe"
    

希望它能帮助您处理您的用例。

更新

Here你可以找到更多关于如何控制索引映射的信息。

【讨论】:

  • 如何将字段改为未分析?
  • @DamForums 你如何创建索引,或者你只是不创建索引,并且在第一个文档被索引时创建索引?
  • @DamForums 对不起,我不是 php 人,但也许这个链接可以帮助你处理这个问题elastic.co/guide/en/elasticsearch/client/php-api/current/…
  • :是的,当创建第一个文档然后创建索引时。
  • @DamForums 所以我猜你必须明确创建索引,然后才能索引第一个文档。希望我之前的链接能为您指明方向。
【解决方案2】:

我认为默认情况下会应用标准标记器。

在这种情况下,它会将文本 john doe 视为短语。

所以试试词组搜索

"full_name" => "\"john doe\""

【讨论】:

  • 这不是最好的方法,因为您使用 Lucene 正则表达式引擎进行搜索,如果存在一些未转义的字符,这将导致查询抛出异常。
  • @fjcero 我只对当前案例做出了快速回答:)
  • 太棒了!我必须与 ES 允许的一些解决方案作斗争,但是当应用程序增长时,这些事情有点混乱:P
  • @PandiyanCool:这对我的问题不起作用。你能帮帮我吗?
  • 尝试使用 match_phrase
【解决方案3】:

如果你想考虑空格,你可以这样做:

{
    "match" : {
         "full_name" : {
            "query" : "john doe",
            "operator" : "and",
            "zero_terms_query": "all"
        }
    }
}

检查这个:https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html

【讨论】:

  • :这不匹配。我需要通配符搜索。当我尝试使用搜索给定的代码时,它不起作用。
猜你喜欢
  • 2021-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 2021-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多