Elasticsearch:针对_all的查询有效但不针对特定字段进行查询

时间:2014-11-04 17:02:58

标签: elasticsearch field return-value analyzer

当我查询_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"
            }
          }
        }
      ]
    }
  }
}

" all"查询结果

{
  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: [ ]
  }
}

3 个答案:

答案 0 :(得分:0)

问题是你的"模式" tokenizer将文本拆分为hello, i am paulgeorge注意#34之前的空白; george" )。为了matchgeorge,你需要摆脱那个空白。

这是一种方法 - 使用模式标记器和自定义过滤器列表定义您自己的自定义分析器(其中" 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"
      }
    }
  }
}

答案 1 :(得分:0)

我使用 multi_term 类型以多种方式分析和存储字段。可以在此处找到相关文档http://www.elasticsearch.org/guide/en/elasticsearch/reference/0.90/mapping-multi-field-type.html 一个分析器可以为您提供您想要的特定类型的查询或聚合的令牌,另一个可以针对相同数据的不同类型的查询提供。

我不确定为什么会出现这个错误(在原始问题中提到),但我想要实现的是使用分析器来创建令牌&#34 ;;"作为代币之间的中断。我想要这个,以便我可以在令牌上进行热门命中聚合(由""分隔的术语分组)。但我希望能够使用单个单词(如标准分析器)搜索/查询数据,而不必查询整个令牌(术语分组)。为了达到这个目的,我刚刚定义了"类型" for" field"和" field2" as" multi_field"然后定义到子字段。一个子字段使用"标准"分析仪和" analyzer_name" (自定义模式分析器)。标准分析器的字段是将运行查询的字段,而另一个字段(使用" analyzer_name"分析器)将用于聚合。

答案 2 :(得分:0)

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

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

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

***这里的问题是查询。使用匹配查询时使用“标准”分析器(默认分析器)。这意味着查询“hello”正在搜索令牌“hello”,但存储的令牌实际上是“你好,我是保罗”而查询“你好我是保罗”实际上是搜索令牌“你好”,“我“,”anm“和”paul“与存储在字段中的任何令牌都不匹配。

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