【问题标题】:Make elasticsearch only return certain fields?让elasticsearch只返回某些字段?
【发布时间】:2012-03-25 04:56:37
【问题描述】:

我正在使用 elasticsearch 来索引我的文档。

是否可以指示它只返回特定字段而不是它存储的整个 json 文档?

【问题讨论】:

标签: elasticsearch


【解决方案1】:

有几种方法可用于实现特定领域的结果。 一种可以通过source方法。 filter_pathfilter_path

文档 Json:

"hits" : [
  {
    "_index" : "xxxxxx",
    "_type" : "_doc",
    "_id" : "xxxxxx",
    "_score" : xxxxxx,
    "_source" : {
      "year" : 2020,
      "created_at" : "2020-01-29",
      "url" : "www.github.com/mbarr0987",
      "name":"github"
    }
  }

查询:

GET bot1/_search?filter_path=hits.hits._source.url
{
  "query": {
    "bool": {
      "must": [
        {"term": {"name.keyword":"github" }}
       ]
    }
  }
}

输出:

{
  "hits" : {
    "hits" : [
      {
        "_source" : {
          "url" : "www.github.com/mbarr0987"
            }
          }
      ]
   }
}

【讨论】:

    【解决方案2】:

    response_filtering

    所有 REST API 都接受一个 filter_path 参数,该参数可用于 减少elasticsearch返回的响应。该参数采用 用点表示法表示的过滤器的逗号分隔列表。

    https://stackoverflow.com/a/35647027/844700

    【讨论】:

      【解决方案3】:

      这是另一个解决方案,现在使用 ma​​tch 表达式

      Source filtering 允许控制每次点击时如何返回 _source 字段。

      使用 Elastiscsearch 5.5 版测试

      关键字includes 定义了具体字段。

      GET /my_indice/my_indice_type/_search
      {
        "_source": {
          "includes": [
            "my_especific_field"
          ]
        },
        "query": {
          "bool": {
            "must": [
              {
                "match": {
                  "_id": "%my_id_here_without_percent%"
                }
              }
            ]
          }
        }
      }
      

      【讨论】:

        【解决方案4】:
        here you can specify whichever field you want in your output and also which you don't.
          
          POST index_name/_search
            {
                "_source": {
                    "includes": [ "field_name", "field_name" ],
                    "excludes": [ "field_name" ]
                },
                "query" : {
                    "match" : { "field_name" : "value" }
                }
            }
        

        【讨论】:

          【解决方案5】:

          对于 ES 版本 5.X 及更高版本,您可以进行 ES 查询,如下所示:

              GET /.../...
              {
                "_source": {
                  "includes": [ "FIELD1", "FIELD2", "FIELD3" ... " ]
                },
                .
                .
                .
                .
              }
          

          【讨论】:

            【解决方案6】:

            是的,使用更好的选项source filter。如果您使用 JSON 进行搜索,它将看起来像这样:

            {
                "_source": ["user", "message", ...],
                "query": ...,
                "size": ...
            }
            

            在 ES 2.4 及更早版本中,您还可以使用fields option to the search API

            {
                "fields": ["user", "message", ...],
                "query": ...,
                "size": ...
            }
            

            这在 ES 5+ 中已弃用。而且源过滤器更强大!

            【讨论】:

            • 确保将它们定义为“已存储”:在映射中为 true。否则 ES 仍然会加载 _source 文档并从那里加载字段。如果返回的数据相对于整个文档的大小而言相对较小,可能会影响性能。
            • 你的意思是“商店”:真的
            • 这些是在 conf 文件中制作的还是在哪里制作的?
            • @vbNewbie:您在哪里定义映射。如果您没有明确定义映射并依赖 ES 来生成它,那么您必须为希望 ES 存储的字段定义映射。您可以仅为需要特殊行为的字段(例如“store”:true、“index”:“not_analyzed”)或所有字段定义映射。查看映射文档以获取更多详细信息。
            • 新版本不再支持字段。改用stored_fields :)
            【解决方案7】:

            如果你知道sql,请写一个查询来获取代码的值,例如sql查询等效和elasticsearch查询

            POST /_sql/translate
            {
              
              "query": "select name,surname from users"
            }
            

            结果是,仔细看包含键

            {
              "size" : 1000,
              "_source" : {
                "includes" : [
                  "name",
                  "surname"
                ],
                "excludes" : [ ]
              },
              "sort" : [
                {
                  "_doc" : {
                    "order" : "asc"
                  }
                }
              ]
            }
            
            

            【讨论】:

              【解决方案8】:

              例如,您有一个包含三个字段的文档:

              PUT movie/_doc/1
              {
                "name":"The Lion King",
                "language":"English",
                "score":"9.3"
              }
              

              如果要返回namescore可以使用以下命令:

              GET movie/_doc/1?_source_includes=name,score
              

              如果你想得到一些匹配模式的字段:

              GET movie/_doc/1?_source_includes=*re
              

              可能会排除一些字段:

              GET movie/_doc/1?_source_excludes=score
              

              【讨论】:

                【解决方案9】:

                我发现get api 的文档很有帮助 - 尤其是两个部分,源过滤字段https://www.elastic.co/guide/en/elasticsearch/reference/7.3/docs-get.html#get-source-filtering

                他们声明了源过滤:

                如果您只需要完整 _source 中的一两个字段,您可以 使用 _source_include 和 _source_exclude 参数包含或 过滤掉你需要的部分。这对于 部分检索可以节省网络开销的大型文档

                这非常适合我的用例。我最终只是像这样过滤源(使用速记):

                {
                    "_source": ["field_x", ..., "field_y"],
                    "query": {      
                        ...
                    }
                }
                

                仅供参考,他们在文档中说明了 fields 参数:

                get 操作允许指定一组存储字段,这些字段将 通过传递 fields 参数返回。

                它似乎适合专门存储的字段,它将每个字段放在一个数组中。如果指定的字段尚未存储,它将从 _source 中获取每个字段,这可能会导致“较慢”的检索。我也很难让它返回对象类型的字段。

                因此,总而言之,您有两个选择,通过源过滤或 [存储] 字段。

                【讨论】:

                • 帮我解决了这个问题。我在使用“字段”返回 geo_point 时遇到问题,但“_source”工作得很好,谢谢!
                【解决方案10】:

                是的,通过使用源过滤器你可以做到这一点,这里是文档source-filtering

                示例请求

                POST index_name/_search
                 {
                   "_source":["field1","filed2".....] 
                 }
                

                输出将是

                {
                  "took": 57,
                  "timed_out": false,
                  "_shards": {
                    "total": 5,
                    "successful": 5,
                    "skipped": 0,
                    "failed": 0
                  },
                  "hits": {
                    "total": 1,
                    "max_score": 1,
                    "hits": [
                      {
                        "_index": "index_name",
                        "_type": "index1",
                        "_id": "1",
                        "_score": 1,
                        "_source": {
                          "field1": "a",
                          "field2": "b"
                        },
                        {
                          "field1": "c",
                          "field2": "d"
                        },....
                      }
                    ]
                  }
                }
                

                【讨论】:

                  【解决方案11】:

                  可以使用“_source”参数发出 REST API GET 请求。

                  示例请求

                  http://localhost:9200/opt_pr/_search?q=SYMBOL:ITC AND OPTION_TYPE=CE AND TRADE_DATE=2017-02-10 AND EXPIRY_DATE=2017-02-23&_source=STRIKE_PRICE
                  

                  回应

                  {
                  "took": 59,
                  "timed_out": false,
                  "_shards": {
                      "total": 5,
                      "successful": 5,
                      "failed": 0
                  },
                  "hits": {
                      "total": 104,
                      "max_score": 7.3908954,
                      "hits": [
                          {
                              "_index": "opt_pr",
                              "_type": "opt_pr_r",
                              "_id": "AV3K4QTgNHl15Mv30uLc",
                              "_score": 7.3908954,
                              "_source": {
                                  "STRIKE_PRICE": 160
                              }
                          },
                          {
                              "_index": "opt_pr",
                              "_type": "opt_pr_r",
                              "_id": "AV3K4QTgNHl15Mv30uLh",
                              "_score": 7.3908954,
                              "_source": {
                                  "STRIKE_PRICE": 185
                              }
                          },
                          {
                              "_index": "opt_pr",
                              "_type": "opt_pr_r",
                              "_id": "AV3K4QTgNHl15Mv30uLi",
                              "_score": 7.3908954,
                              "_source": {
                                  "STRIKE_PRICE": 190
                              }
                          },
                          {
                              "_index": "opt_pr",
                              "_type": "opt_pr_r",
                              "_id": "AV3K4QTgNHl15Mv30uLm",
                              "_score": 7.3908954,
                              "_source": {
                                  "STRIKE_PRICE": 210
                              }
                          },
                          {
                              "_index": "opt_pr",
                              "_type": "opt_pr_r",
                              "_id": "AV3K4QTgNHl15Mv30uLp",
                              "_score": 7.3908954,
                              "_source": {
                                  "STRIKE_PRICE": 225
                              }
                          },
                          {
                              "_index": "opt_pr",
                              "_type": "opt_pr_r",
                              "_id": "AV3K4QTgNHl15Mv30uLr",
                              "_score": 7.3908954,
                              "_source": {
                                  "STRIKE_PRICE": 235
                              }
                          },
                          {
                              "_index": "opt_pr",
                              "_type": "opt_pr_r",
                              "_id": "AV3K4QTgNHl15Mv30uLw",
                              "_score": 7.3908954,
                              "_source": {
                                  "STRIKE_PRICE": 260
                              }
                          },
                          {
                              "_index": "opt_pr",
                              "_type": "opt_pr_r",
                              "_id": "AV3K4QTgNHl15Mv30uL5",
                              "_score": 7.3908954,
                              "_source": {
                                  "STRIKE_PRICE": 305
                              }
                          },
                          {
                              "_index": "opt_pr",
                              "_type": "opt_pr_r",
                              "_id": "AV3K4QTgNHl15Mv30uLd",
                              "_score": 7.381078,
                              "_source": {
                                  "STRIKE_PRICE": 165
                              }
                          },
                          {
                              "_index": "opt_pr",
                              "_type": "opt_pr_r",
                              "_id": "AV3K4QTgNHl15Mv30uLy",
                              "_score": 7.381078,
                              "_source": {
                                  "STRIKE_PRICE": 270
                              }
                          }
                      ]
                  }
                  

                  }

                  【讨论】:

                  • 这对我来说非常有用。
                  【解决方案12】:

                  在java中你可以像这样使用setFetchSource:

                  client.prepareSearch(index).setTypes(type)
                              .setFetchSource(new String[] { "field1", "field2" }, null)
                  

                  【讨论】:

                    【解决方案13】:

                    在 Elasticsearch 5.x 中,不推荐使用上述方法。 您可以使用 _source 方法,但在某些情况下,存储字段是有意义的。例如,如果您有一个包含标题、日期和非常大的内容字段的文档,您可能只想检索标题和日期,而不必从大的 _source 字段中提取这些字段:

                    在这种情况下,你会使用:

                    {  
                       "size": $INT_NUM_OF_DOCS_TO_RETURN,
                       "stored_fields":[  
                          "doc.headline",
                          "doc.text",
                          "doc.timestamp_utc"
                       ],
                       "query":{  
                          "bool":{  
                             "must":{  
                                "term":{  
                                   "doc.topic":"news_on_things"
                                }
                             },
                             "filter":{  
                                "range":{  
                                   "doc.timestamp_utc":{  
                                      "gte":1451606400000,
                                      "lt":1483228800000,
                                      "format":"epoch_millis"
                                   }
                                }
                             }
                          }
                       },
                       "aggs":{  
                    
                       }
                    }
                    

                    请参阅有关如何索引存储字段的文档。 总是为 Upvote 感到高兴!

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2016-09-01
                      相关资源
                      最近更新 更多