【问题标题】:Elasticsearch queries on "empty index"Elasticsearch 查询“空索引”
【发布时间】:2014-05-30 23:33:03
【问题描述】:

在我的应用程序中,我使用了几个 elasticsearch 索引,它们在初始状态下不包含索引文档。我认为这可以称为“空”:) 文档的映射正确且有效。

该应用程序还有一个包含实体的关系数据库,这些实体可能具有在 elasticsearch 中关联的文档。

在应用程序的初始状态中,只有实体没有文档是很常见的,因此没有一个文档被索引,因此是“空索引”。尽管如此,索引已创建,并且文档的映射已被放入索引并存在于索引元数据中。

无论如何,当我使用 SearchQuery 查询 elasticsearch 以查找其中一个实体的文档(文档包含实体的唯一 ID)时,elasticsearch 将抛出 ElasticSearchException,抱怨字段 xy 等不存在映射。

但是如果我先在索引中插入一个空白文档,则查询不会失败。

有没有办法“初始化”索引以防止查询失败并摆脱愚蠢的“虚拟文档解决方法”?

更新: 另外,使用虚拟文档的解决方法会污染索引,例如,计数查询现在总是返回 +1....所以我也在解决方法中添加了删除...

【问题讨论】:

  • 您是在定义映射还是 Elasticsearch 根据索引自动检测您的映射?
  • 不,我为每种文档类型明确定义了映射。

标签: exception search indexing elasticsearch mapping


【解决方案1】:

您的问题缺乏细节且不清楚。如果您提供了索引架构和查询的要点,那将会有所帮助。您还应该提供您正在使用的 elasticsearch 版本。

您提到的“无映射”异常与使用某些数据初始化索引无关。很可能您正在对不存在的字段进行排序。如果您同时查询多个索引,这很常见。

解决方案:解决方案基于elasticsearch的版本。如果您使用的是 1.3.x 或更低版本,那么您应该使用 ignore_unmapped。如果您使用的是高于 1.3.5 的版本,则应使用 unmapped_typeClick here to read official documentation.

如果您发现文档令人困惑,那么这个例子会让您一目了然:

让我们创建两个索引 testindex1testindex2

curl -XPUT localhost:9200/testindex1 -d '{"mappings":{"type1":{"properties":{"firstname":{"type":"string"},"servers":{"type":"nested","properties":{"name":{"type":"string"},"location":{"type":"nested","properties":{"name":{"type":"string"}}}}}}}}}'

curl -XPUT localhost:9200/testindex2 -d '{"mappings":{"type1":{"properties":{"firstname":{"type":"string"},"computers":{"type":"nested","properties":{"name":{"type":"string"},"location":{"type":"nested","properties":{"name":{"type":"string"}}}}}}}}}'

这两个索引之间的唯一区别是 - testindex1 具有“server”字段,而 textindex2 具有“computers”字段。

现在让我们在两个索引中插入测试数据。

testindex1上的索引测试数据:

curl -XPUT localhost:9200/testindex1/type1/1 -d '{"firstname":"servertom","servers":[{"name":"server1","location":[{"name":"location1"},{"name":"location2"}]},{"name":"server2","location":[{"name":"location1"}]}]}'

curl -XPUT localhost:9200/testindex1/type1/2 -d '{"firstname":"serverjerry","servers":[{"name":"server2","location":[{"name":"location5"}]}]}'

testindex2上的索引测试数据:

curl -XPUT localhost:9200/testindex2/type1/1 -d '{"firstname":"computertom","computers":[{"name":"computer1","location":[{"name":"location1"},{"name":"location2"}]},{"name":"computer2","location":[{"name":"location1"}]}]}'

curl -XPUT localhost:9200/testindex2/type1/2 -d '{"firstname":"computerjerry","computers":[{"name":"computer2","location":[{"name":"location5"}]}]}'

查询示例:

  1. 使用“unmapped_type”表示 elasticsearch 版本 > 1.3.x

        curl -XPOST 'localhost:9200/testindex2/_search?pretty' -d '{"fields":["firstname"],"query":{"match_all":{}},"sort":[{"servers.location.name":{"order":"desc","unmapped_type":"string"}}]}'
    
  2. 对 elasticsearch 版本使用“ignore_unmapped

    curl -XPOST 'localhost:9200/testindex2/_search?pretty' -d '{"fields":["firstname"],"query":{"match_all":{}},"sort":[{"servers.location.name":{"order":"desc","ignore_unmapped":"true"}}]}'
    

查询 1 的输出

{
  "took" : 15,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : null,
    "hits" : [ {
      "_index" : "testindex2",
      "_type" : "type1",
      "_id" : "1",
      "_score" : null,
      "fields" : {
        "firstname" : [ "computertom" ]
      },
      "sort" : [ null ]
    }, {
      "_index" : "testindex2",
      "_type" : "type1",
      "_id" : "2",
      "_score" : null,
      "fields" : {
        "firstname" : [ "computerjerry" ]
      },
      "sort" : [ null ]
    } ]
  }
}

查询2的输出

{
  "took" : 10,
  "timed_out" : false,
  "_shards" : {
    "total" : 5,
    "successful" : 5,
    "failed" : 0
  },
  "hits" : {
    "total" : 2,
    "max_score" : null,
    "hits" : [ {
      "_index" : "testindex2",
      "_type" : "type1",
      "_id" : "1",
      "_score" : null,
      "fields" : {
        "firstname" : [ "computertom" ]
      },
      "sort" : [ -9223372036854775808 ]
    }, {
      "_index" : "testindex2",
      "_type" : "type1",
      "_id" : "2",
      "_score" : null,
      "fields" : {
        "firstname" : [ "computerjerry" ]
      },
      "sort" : [ -9223372036854775808 ]
    } ]
  }
}

注意:

  1. 这些示例是在 elasticserch 1.4 上创建的。
  2. 这些示例还演示了如何对嵌套字段进行排序。

【讨论】:

    【解决方案2】:

    您在搜索时是否在进行排序?我遇到了同样的问题("No mapping found for [field] in order to sort on"),但仅在尝试对结果进行排序时。在这种情况下,解决方案只需将ignore_unmapped: true 属性添加到查询中的sort 参数:

    {
      ...
      "body": {
        ...
        "sort": [
          {"field_name": {
            "order": "asc",
            "ignore_unmapped": true
          }}
        ]
        ...
      }
      ...
    }
    

    我在这里找到了我的解决方案: No mapping found for field in order to sort on in ElasticSearch

    【讨论】:

      猜你喜欢
      • 2018-05-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 2014-08-10
      • 1970-01-01
      • 1970-01-01
      • 2017-04-02
      相关资源
      最近更新 更多