elasticsearch Elasticsearch 2.4中数组字段匹配过滤器的不同值,elasticsearch,elasticsearch" /> elasticsearch Elasticsearch 2.4中数组字段匹配过滤器的不同值,elasticsearch,elasticsearch" />

elasticsearch Elasticsearch 2.4中数组字段匹配过滤器的不同值

elasticsearch Elasticsearch 2.4中数组字段匹配过滤器的不同值,elasticsearch,elasticsearch,简而言之:我想在文档的某些字段中查找不同的值,但只匹配某些筛选器。问题出在数组字段中。 假设ES 2.4中有以下文档: [ { "states": [ "Washington (US-WA)", "California (US-CA)" ] }, { "states": [ "Washington (US-WA)" ] } ] 我希望我的用户能够通过typeahead查找所有可能的状态,因此我对“wa”用户请求

简而言之:我想在文档的某些字段中查找不同的值,但只匹配某些筛选器。问题出在数组字段中。 假设ES 2.4中有以下文档:

[
  {
    "states": [
      "Washington (US-WA)",
      "California (US-CA)"
    ]
  },
  {
    "states": [
      "Washington (US-WA)"
    ]
  }
]
我希望我的用户能够通过typeahead查找所有可能的状态,因此我对“wa”用户请求有以下查询:

{
  "query": {
    "wildcard": {
      "states.raw": "*wa*"
    }
  },
  "aggregations": {
    "typed": {
      "terms": {
        "field": "states.raw"
      },
      "aggregations": {
        "typed_hits": {
          "top_hits": {
            "_source": { "includes": ["states"] }
          }
        }
      }
    }
  }
}
状态。原始
是一个子字段,带有
未分析
选项

除非我有一个像示例中那样的值数组,否则这个查询工作得非常好——它同时返回华盛顿和加利福尼亚。我确实理解发生这种情况的原因(查询和聚合在文档顶部工作,文档包含这两个选项,尽管只有一个选项与过滤器匹配),但我真的只想看到华盛顿,不想在应用程序端为ES结果添加另一层过滤

是否有办法通过单个ES 2.4请求实现此目的?

您可以使用“筛选值”功能(请参阅)。 因此,您的请求可能如下所示:

POST /index/collection/_search?size=0
{
  "aggregations": {
    "typed": {
      "terms": {
        "field": "states.raw",
        "include": ".*wa.*" // You need to carefully quote the "wa" string because it'll be used as part of RegExp
      },
      "aggregations": {
        "typed_hits": {
          "top_hits": {
            "_source": { "includes": ["states"] }
          }
        }
      }
    }
  }
}

不过,我无法控制自己,也不能告诉您,使用带前导通配符的
通配符
并不是最好的解决方案。请,请考虑使用<代码> ngc>代码>此< /强>:

PUT states
{
  "settings": {
    "analysis": {
      "filter": {
        "ngrams": {
          "type": "nGram",
          "min_gram": "2",
          "max_gram": "20"
        }
      },
      "analyzer": {
        "ngram_analyzer": {
          "type": "custom",
          "filter": [
            "standard",
            "lowercase",
            "ngrams"
          ],
          "tokenizer": "standard"
        }
      }
    }
  },
  "mappings": {
    "doc": {
      "properties": {
        "location": {
          "properties": {
            "states": {
              "type": "string",
              "fields": {
                "raw": {
                  "type": "string",
                  "index": "not_analyzed"
                },
                "ngrams": {
                  "type": "string",
                  "analyzer": "ngram_analyzer"
                }
              }
            }
          }
        }
      }
    }
  }
}


POST states/doc/1
{
  "text":"bla1",
  "location": [
    {
      "states": [
        "Washington (US-WA)",
        "California (US-CA)"
      ]
    },
    {
      "states": [
        "Washington (US-WA)"
      ]
    }
  ]
}
POST states/doc/2
{
  "text":"bla2",
  "location": [
    {
      "states": [
        "Washington (US-WA)",
        "California (US-CA)"
      ]
    }
  ]
}
POST states/doc/3
{
  "text":"bla3",
  "location": [
    {
      "states": [
        "California (US-CA)"
      ]
    },
    {
      "states": [
        "Illinois (US-IL)"
      ]
    }
  ]
}
最后一个问题是:

GET states/_search
{
  "query": {
    "term": {
      "location.states.ngrams": {
        "value": "sh"
      }
    }
  },
  "aggregations": {
    "filtering_states": {
      "terms": {
        "field": "location.states.raw",
        "include": ".*sh.*"
      },
      "aggs": {
        "typed_hits": {
          "top_hits": {
            "_source": {
              "includes": [
                "location.states"
              ]
            }
          }
        }
      }
    }
  }
}

我一直在查看
include
,虽然没有正确使用它,也错过了自己找到答案的机会,但感谢
ngrams
,但我们的需求确实需要它以这种方式工作,我知道这很遗憾。无法将您的答案标记为正确答案,因为@igelbox之前提供了相同的查询,这是不公平的,抱歉。呵呵,不用担心答案。我以前听说过对“按原样使用”和“不能更改”的限制。不幸的是,这些用户只有在遇到性能问题时才会做出必要的更改,通常是在集群中的数据量增加或请求数量增加之后。当这种情况发生时,环境可能已经受到严重影响。在这一点上,映射的改变将对集群整体产生更大的影响。这是完全公平的,你应该知道,我从我这边做了一切来改变这一点,但没有运气。也许,当我们遇到性能问题时,我们会改变它。这对每个人都是一个很好的教训:)