首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在弹性搜索中查找不同的内部对象

在弹性搜索中查找不同的内部对象
EN

Stack Overflow用户
提问于 2015-10-26 15:18:40
回答 2查看 4K关注 0票数 3

我们试图在Elasticsearch中找到不同的内部对象。对于我们的情况来说,这将是一个最小的例子。我们被以下映射所困扰(更改类型或索引或添加新字段不是问题,但结构应该保持原样):

代码语言:javascript
复制
{
  "building": {
    "properties": {
      "street": {
        "type": "string",
        "store": "yes",
        "index": "not_analyzed"
      },
      "house number": {
        "type": "string",
        "store": "yes",
        "index": "not_analyzed"
      },
      "city": {
        "type": "string",
        "store": "yes",
        "index": "not_analyzed"
      },
      "people": {
        "type": "object",
        "store": "yes",
        "index": "not_analyzed",
        "properties": {
          "firstName": {
            "type": "string",
            "store": "yes",
            "index": "not_analyzed"
          },
          "lastName": {
            "type": "string",
            "store": "yes",
            "index": "not_analyzed"
          }
        }
      }
    }
  }
}

假设我们有这个示例数据:

代码语言:javascript
复制
{
  "buildings": [
    {
      "street": "Baker Street",
      "house number": "221 B",
      "city": "London",
      "people": [
        {
          "firstName": "John",
          "lastName": "Doe"
        },
        {
          "firstName": "Jane",
          "lastName": "Doe"
        }
      ]
    },
    {
      "street": "Baker Street",
      "house number": "5",
      "city": "London",
      "people": [
        {
          "firstName": "John",
          "lastName": "Doe"
        }
      ]
    },
    {
      "street": "Garden Street",
      "house number": "1",
      "city": "London",
      "people": [
        {
          "firstName": "Jane",
          "lastName": "Smith"
        }
      ]
    }
  ]
}

当我们查询街道“贝克街”(以及所需的任何其他选项)时,我们希望得到以下列表:

代码语言:javascript
复制
[
    {
      "firstName": "John",
      "lastName": "Doe"
    },
    {
      "firstName": "Jane",
      "lastName": "Doe"
    }
]

格式并不重要,但是我们应该能够解析名字和姓氏。只是,由于我们的实际数据集要大得多,我们需要的条目是不同的。

我们正在使用Elasticsearch 1.7。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-10-27 12:24:49

我们终于解决了问题。

我们的解决方案是(正如我们预期的)一个预先计算的people_all字段.但是,我们不是使用copy_totransform,而是在导入数据时编写其他字段。该领域如下:

代码语言:javascript
复制
"people": {
  "type": "nested",
  ..
  "properties": {
    "firstName": {
      "type": "string",
      "store": "yes",
      "index": "not_analyzed"
    },
    "lastName": {
      "type": "string",
      "store": "yes",
      "index": "not_analyzed"
    },
    "people_all": {
      "type": "string",
      "index": "not_analyzed"
    }
  }
}

请注意"index": "not_analyzed"people_all字段。这是重要的,有完整的桶。如果您不使用它,我们的示例将返回3个桶"john“、"jane”和"doe“。

在编写完这个新字段之后,我们可以按以下方式运行一个扩展:

代码语言:javascript
复制
{
  "size": 0,
  "query": {
    "term": {
      "street": "Baker Street"
    }
  },
  "aggs": {
    "people_distinct": {
      "nested": {
        "path": "people"
      },
      "aggs": {
        "people_all_distinct": {
          "terms": {
            "field": "people.people_all",
            "size": 0
          }
        }
      }
    }
  }
}

我们将返回以下答复:

代码语言:javascript
复制
{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0.0,
    "hits": []
  },
  "aggregations": {
    "people_distinct": {
      "doc_count": 3,
      "people_name_distinct": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "John Doe",
            "doc_count": 2
          },
          {
            "key": "Jane Doe",
            "doc_count": 1
          }
        ]
      }
    }
  }
}

从响应中的桶中,我们现在能够创建不同的人员对象。

请告诉我们是否有更好的方法来达到我们的目标。解析桶不是一个最优的解决方案,如果每个桶中都有字段firstNamelastName,那就更好了。

票数 3
EN

Stack Overflow用户

发布于 2015-10-26 17:24:54

正如注释中所建议的那样,您对人员的映射应该是nested类型,而不是object类型,因为它可能会产生意想不到的结果。在此之后,还需要重新编制数据索引。

至于这个问题,您需要根据您的查询来聚合结果。

代码语言:javascript
复制
{
  "query": {
    "term": {
      "street": "Baker Street"
    }
  },
  "aggs": {
    "distinct_people": {
      "terms": {
        "field": "people",
        "size": 1000
      }
    }
  }
}

请注意,我已经将size设置为1000内部聚合,您可能需要使用更大的数字来获取所有不同的人,ES默认只返回10个结果。

如果您只对聚合桶感兴趣,可以将查询size设置为0,或者使用参数search_type=count。您可以在这里阅读更多关于聚合的内容。https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html

我希望这能帮上忙!如果这件事没有解决,请告诉我。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33349315

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档