【问题标题】:ElasticSearch: How to return only specific fields using ElasticSearch API?ElasticSearch:如何使用 ElasticSearch API 仅返回特定字段?
【发布时间】:2020-01-05 22:47:19
【问题描述】:

我正在使用 ElasticSearch 7.3 来查询一些文档,
我只想在查询响应中返回每个文档的特定字段,
我发现_source可以用来实现这个,
我可以使用此查询从 Kibana 执行此操作 -

GET /test/_search?_source=id
{
  "query": {
    "match_all": {}
  }
}

返回正确的数据 -

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 6,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.0,
        "_source" : {
          "id" : 3
        }
      },
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 1.0,
        "_source" : {
          "id" : 2
        }
      },
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 1.0,
        "_source" : { }
      },
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "4",
        "_score" : 1.0,
        "_source" : {
          "id" : 4
        }
      },
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "5",
        "_score" : 1.0,
        "_source" : {
          "id" : 5
        }
      },
      {
        "_index" : "test",
        "_type" : "_doc",
        "_id" : "6",
        "_score" : 1.0,
        "_source" : {
          "id" : 6
        }
      }
    ]
  }
}

但我无法使用 ElasticSearch 的节点客户端实现相同的功能 -

const { Client } = require('@elastic/elasticsearch')
const client = new Client({ node: 'http://localhost:9200' })

let searchTest = async () => {
  let indexToQuery = 'test';
  let esQuery = {
    index: indexToQuery,
    //q: '_source:id',
    body: {
        "query": {
          "match_all": {}
        }
    }
  };
  console.log('esQuery =>\n', esQuery);

  const result = await client.search(esQuery);
  console.log("search resp => \n", result.body.hits.hits);
};

searchTest();

有人可以帮我找到实现我的用例的正确方法吗?

参考资料 -
https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html#get-source-filtering
https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/16.x/api-reference.html#api-search

【问题讨论】:

    标签: node.js elasticsearch


    【解决方案1】:

    _source 也可以用作查询的一部分。在 body 块中添加 _source 作为 query 的兄弟姐妹。更新如下:

    {
      "query": {
        "match_all": {}
      },
      "_source": ["id"]
    }
    

    【讨论】:

    • 这对我来说是个救星。 :) 还有问题。 :D
    【解决方案2】:

    您可以使用 _source 控制应从搜索结果中检索的字段。

    请注意,如果您在搜索查询中使用聚合并且只对它们的结果(= 存储桶)感兴趣,您会在 _source-field 之外找到它们。因此你可以设置

    "_source": false
    

    避免获取 _source 下的所有字段并略微提高查询的性能。

    --- 编辑 ---

    这是一个示例查询,它使用 kibana 样本航班数据上的术语聚合来获取每个目的地机场 id 的点击量:

    GET kibana_sample_data_flights/_search
    {
      "_source": false, 
      "query": {
        "match_all": {}
      },
      "aggs": {
        "airport_id_agg": {
          "terms": {
            "field": "DestAirportID"
          }
        }
    }
    

    }

    响应如下所示:

    "hits" : {
    "total" : {
      "value" : 10000,
      "relation" : "gte"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "kibana_sample_data_flights",
        "_type" : "_doc",
        "_id" : "K-Aj6mwBFbrhq0Rw_O-6",
        "_score" : 1.0
      },
      ...
      ]
      },
      "aggregations" : {
        "airport_id_agg" : {
          "doc_count_error_upper_bound" : 0,
          "sum_other_doc_count" : 8898,
          "buckets" : [
            {
              "key" : "ZRH",
              "doc_count" : 691
            },
            {
              "key" : "XIY",
              "doc_count" : 526
            },
            {
              "key" : "YWG",
              "doc_count" : 460
            },
            ...
          ]
        }
      }
    

    如您所见,响应不包含任何数据字段。将此搜索查询的结果与Elastic Demo Page 上未设置 "_source": false 的结果进行比较

    【讨论】:

    • 你能发布一个示例查询吗?
    • @AniruddhaRaje 我用示例查询更新了我的答案。
    • @apt-get_install_skill 如果您希望不返回任何字段,最好使用"_source": false 而不是"_source": [""]
    • @NishantSaini 感谢您的提示!更新了我的答案并按照您的提示工作。
    猜你喜欢
    • 2012-07-03
    • 2015-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    相关资源
    最近更新 更多