【问题标题】:Elasticsearch: query against _all works but not query against specific fieldElasticsearch:查询 _all 有效,但不能查询特定字段
【发布时间】:2014-11-04 17:02:58
【问题描述】:

当我查询 _all 字段的数据时,Elasticsearch 返回两个文档(文档中都只有一个字段)。但是,当我执行相同的查询时,除了将要查询的字段从 _all 更改为返回文档中某个字段的名称之外,Elasticsearch 什么也不返回。这似乎发生在query_string 查询以及此处显示的match 查询中。任何想法这是发生了什么以及如何解决它?

这是映射

analyzertestpatternsemi: {
  mappings: {
    content: {
      properties: {
        field: {
          type: string
          store: true
          term_vector: with_positions_offsets
          index_analyzer: analyzer_name
        }
        field2: {
          type: string
          store: true
          index_analyzer: analyzer_name
        }
      }
    }
  }
}

这是设置

{
  analyzertestpatternsemi: {
    settings: {
      index: {
        uuid: _W55phRKQ1GylWU5JleArg
          analysis: {
            analyzer: { 
              whitespace: {
                type: custom
                fields: [
                  lowercase
                ]
                tokenizer: whitespace
              }
              analyzer_name: {
                preserve_original: true
                type: pattern
                pattern: ;
              }
            }
          }
          number_of_replicas: 1
          number_of_shards: 5
          version: {
          created: 1030299
          }
        }
      }
    }
  }

文档

{
  _index: analyzertestpatternsemi
  _type: content
  _id: 3
  _version: 1
  found: true
   _source: {
    field2: Hello, I am Paul; George
  }
}

{
  _index: analyzertestpatternsemi
  _type: content
  _id: 2
  _version: 1
  found: true
    _source: {
      field: Hello, I am Paul; George
  }
}

获取_id 的词向量给出

georgehello, i am paul

“_all”查询

curl -XGET http://localhost:9200/analyzertestpatternsemi/_search?
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "_all": {
              "query": "george",
              "type": "phrase"
            }
          }
        }
      ]
    }
  }
}

“所有”查询结果

{
  took: 2
  timed_out: false
  _shards: {
    total: 2
    successful: 2
    failed: 0
  }
  hits: {
    total: 2
    max_score: 0.4375
    hits: [
      {
        _index: analyzertestpatternsemi
        _type: content
        _id: 2
        _score: 0.4375
        _source: {
          field: Hello, I am Paul; George
        }
      }
      {
        _index: analyzertestpatternsemi
        _type: content
        _id: 3
        _score: 0.13424811
        _source: {
          field2: Hello, I am Paul; George
        }
      }
    ]
  }
}

*** 相同的查询,但在字段中搜索:“字段”

curl -XGET http://localhost:9200/analyzertestpatternsemi/_search?
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "field": {
              "query": "george",
              "type": "phrase"
            }
          }
        }
      ]
    }
  }
}

“字段”查询结果

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

相同的查询,但在字段中搜索:“field2”

curl -XGET http://localhost:9200/analyzertestpatternsemi/_search?
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "field2": {
              "query": "george",
              "type": "phrase"
            }
          }
        }
      ]
    }
  }
}

“field2”查询结果

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

【问题讨论】:

    标签: elasticsearch field return-value analyzer


    【解决方案1】:

    问题是您的“模式”标记器将文本拆分为hello, i am paulgeorge注意“george”之前的空格)。为了能够为george 发送match,您需要去掉那个空格。

    这是一种方法 - 使用模式标记器和自定义过滤器列表定义您自己的自定义分析器(其中“trim”是修剪标记前后空格所需的添加):

    {
      "mappings": {
        "content": {
          "properties": {
            "field": {
              "type": "string",
              "store": true,
              "term_vector": "with_positions_offsets",
              "index_analyzer": "analyzer_name"
            },
            "field2": {
              "type": "string",
              "store": true,
              "index_analyzer": "analyzer_name"
            }
          }
        }
      },
      "settings": {
        "index": {
          "uuid": "_W55phRKQ1GylWU5JleArg",
          "analysis": {
            "analyzer": {
              "whitespace": {
                "type": "custom",
                "fields": [
                  "lowercase"
                ],
                "tokenizer": "whitespace"
              },
              "analyzer_name": {
                "type": "custom",
                "tokenizer": "my_pattern_tokenizer",
                "filter": ["lowercase","trim"]
              }
            },
            "tokenizer": {
              "my_pattern_tokenizer": {
                "type": "pattern",
                "pattern": ";"
              }
            }
          },
          "number_of_replicas": 1,
          "number_of_shards": 5,
          "version": {
            "created": "1030299"
          }
        }
      }
    }
    

    【讨论】:

    • 感谢您的帮助。这确实解决了专门搜索“george”时的问题,但是当我搜索另一个术语时,我仍然遇到同样的问题(当我在“_all”中搜索但不在“field”或“field2”中搜索时返回文档) . “你好,我是保罗”。我尝试搜索“你好”、“保罗”、“你好我是保罗”、“你好我是保罗”和“你好,我是保罗”;没有一个返回任何东西。
    【解决方案2】:

    我使用 multi_term 类型以多种方式分析和存储字段。它的文档可以在这里找到http://www.elasticsearch.org/guide/en/elasticsearch/reference/0.90/mapping-multi-field-type.html 一种分析器可以为您提供特定类型的查询或聚合所需的标记,而另一种分析器可能用于对同一数据进行不同类型的查询。

    我不确定为什么会发生此错误(在原始问题中提到),但我试图实现的是使用分析器创建带有“;”的标记作为令牌之间的中断。我想要这个,以便我可以根据标记(由“;”分隔的术语分组)进行热门点击聚合。但我希望能够使用单个单词(如标准分析器)搜索/查询数据,而不必查询整个令牌(术语分组)。为此,我刚刚将“field”和“field2”的“type”定义为“multi_field”,然后定义为子字段。一个子字段使用“标准”分析器和“analyzer_name”(自定义模式分析器)。带有标准分析器的字段是查询将针对的字段,另一个字段(带有“analyzer_name”分析器)将用于聚合。

    【讨论】:

    • 嗯,是的,多种搜索方式,多种方式通过不同的标记分析和存储相同的文本。
    【解决方案3】:

    问题实际上出在查询上。存储的两个令牌是“你好,我是保罗”和“乔治”。

    将“trim”过滤器添加到分析器“analyzer name”解决了查询“george”不返回任何内容的问题,因为没有“trim”分析器,存储的术语实际上是“george”。

    当在查询中使用以下内容时,匹配查询不返回文档的问题(在评论中指出 - James 于 11 月 6 日 - 与 Adrei Stefan 于 11 月 5 日的回答相关联):“hello”、“paul ”、“你好我是保罗”、“你好我是保罗”和“你好,我是保罗”解释如下。

    *** 这里的问题在于查询。当使用带有“标准”分析器(默认分析器)的匹配查询时。这意味着查询“hello”正在搜索标记“hello”,但存储的标记实际上是“hello, i am paul”,查询“hello i am paul”实际上搜索标记“hello”、“i "、"anm" 和 "paul" 与字段中存储的任何标记都不匹配。

    在这种情况下,Elasticsearch 只会在它正在搜索的词为“george”或“hello, i am paul”时返回文档。如果您使用这两个标记中的任何一个进行术语搜索或在分析器设置为“关键字”的匹配查询中使用它们,则将返回该文档。如果您将分析器设置为“analyzer_name”,您还可以搜索“你好,我是保罗”、“乔治”、“你好,我是保罗;乔治”或这三个字母中的任何一个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-16
      • 1970-01-01
      • 1970-01-01
      • 2021-05-03
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      相关资源
      最近更新 更多