Elasticsearch聚合将结果转换为小写

时间:2015-09-18 10:00:02

标签: elasticsearch lowercase analyzer elasticsearch-aggregation

我一直在玩ElasticSearch,并在进行聚合时发现了一个问题。

我有两个端点, / A / B 。在第一个我有父母为第二个。因此,B中的一个或多个对象必须属于A中的一个对象。因此,B中的对象具有属性" parentId"使用ElasticSearch生成的父索引。

我想过滤A中的父项属于B的子属性。为了做到这一点,我首先按属性过滤B中的孩子,并获得我以后用来获取父母的独特父ID。

我发送此请求:

POST http://localhost:9200/test/B/_search
{
    "query": {
        "query_string": {
            "default_field": "name",
            "query": "derp2*"
        }
    },
    "aggregations": {
        "ids": {
            "terms": {
                "field": "parentId"
            }
        }
    }
}

得到这个回复:

{
  "took": 91,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 3,
    "max_score": 1,
    "hits": [
      {
        "_index": "test",
        "_type": "child",
        "_id": "AU_fjH5u40Hx1Kh6rfQG",
        "_score": 1,
        "_source": {
          "parentId": "AU_ffvwM40Hx1Kh6rfQA",
          "name": "derp2child2"
        }
      },
      {
        "_index": "test",
        "_type": "child",
        "_id": "AU_fjD_U40Hx1Kh6rfQF",
        "_score": 1,
        "_source": {
          "parentId": "AU_ffvwM40Hx1Kh6rfQA",
          "name": "derp2child1"
        }
      },
      {
        "_index": "test",
        "_type": "child",
        "_id": "AU_fjKqf40Hx1Kh6rfQH",
        "_score": 1,
        "_source": {
          "parentId": "AU_ffvwM40Hx1Kh6rfQA",
          "name": "derp2child3"
        }
      }
    ]
  },
  "aggregations": {
    "ids": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "au_ffvwm40hx1kh6rfqa",
          "doc_count": 3
        }
      ]
    }
  }
}

由于某种原因,过滤后的密钥以小写形式返回,因此无法向ElasticSearch请求父级

GET http://localhost:9200/test/A/au_ffvwm40hx1kh6rfqa

Response:
{
  "_index": "test",
  "_type": "A",
  "_id": "au_ffvwm40hx1kh6rfqa",
  "found": false
}

关于为什么会发生这种情况的任何想法?

2 个答案:

答案 0 :(得分:3)

命中与聚合结果之间的差异在于聚合适用于创建的术语。他们也将退还条款。点击返回原始来源。

这些条款是如何创建的?基于所选的分析仪,在您的情况下是默认的分析仪,标准分析仪。此分析器所做的一件事就是降低术语的所有字符。就像安德烈提到的那样,你应该将字段parentId配置为not_analyzed。

PUT test
{
  "mappings": {
    "B": {
      "properties": {
        "parentId": {
          "type": "string",
          "index": "not_analyzed"
        }
      }
    }
  }   
}

答案 1 :(得分:1)

我来晚了,但是我遇到了同样的问题,并且理解这是由正常化引起的。

如果要防止任何规范化,则必须更改mapping中的index,将合计值更改为小写。

您可以通过输入

来检查DevTools console中的当前映射
GET /A/_mapping
GET /B/_mapping

当您看到索引的结构时,必须查看parentId字段的设置。

如果您不想更改字段的行为,但又想避免聚合期间的规范化,则可以在parentId字段中添加一个子字段。

要更改映射,您必须删除索引并使用新的映射重新创建它:

在您的情况下,它看起来像这样(它仅包含parentId字段)

PUT /B/_mapping
{
  "properties": {
    "parentId": {
      "type": "text",
      "fields": {
        "keyword": {
          "type": "keyword"
        }
      }
    }
  }
}

然后,您必须在查询中使用子字段:

POST http://localhost:9200/test/B/_search
{
  "query": {
    "query_string": {
      "default_field": "name",
      "query": "derp2*"
    }
  },
  "aggregations": {
    "ids": {
      "terms": {
        "field": "parentId.keyword",
        "order": {"_key": "desc"}
      }
    }
  }
}