当前位置: 首页 > 面试题库 >

如何进行elasticsearch查询以过滤字段的最大值?

曹铭晨
2023-03-14
问题内容

我希望能够查询文本,但也只能检索数据中某个整数字段的最大值的结果。我已经阅读了有关聚合和过滤器的文档,但我不太清楚自己在寻找什么。

例如,我有一些重复的数据得到索引,除了整数字段外,这些数据都是相同的-我们称这个字段为lastseen

因此,作为示例,给定将这些数据放入elasticsearch中:

  //  these two the same except "lastseen" field
  curl -XPOST localhost:9200/myindex/myobject -d '{
    "field1": "dinner carrot potato broccoli",
    "field2": "something here",
    "lastseen": 1000
  }'

  curl -XPOST localhost:9200/myindex/myobject -d '{
    "field1": "dinner carrot potato broccoli",
    "field2": "something here",
    "somevalue": 100
  }'

  # and these two the same except "lastseen" field
  curl -XPOST localhost:9200/myindex/myobject -d '{
    "field1": "fish chicken something",
    "field2": "dinner",
    "lastseen": 2000
  }'

  curl -XPOST localhost:9200/myindex/myobject -d '{
    "field1": "fish chicken something",
    "field2": "dinner",
    "lastseen": 200
  }'

如果我查询 "dinner"

  curl -XPOST localhost:9200/myindex -d '{  
   "query": {
        "query_string": {
            "query": "dinner"
        }
    }
    }'

我会得到4个结果。我想要一个过滤器,这样我只能得到两个结果-仅包含具有最大lastseen字段的项目。

显然 不对的 ,但希望它能使您对我的追求有一个了解:

{
    "query": {
        "query_string": {
            "query": "dinner"
        }
    },
    "filter": {
          "max": "lastseen"
        }

}

结果如下所示:

"hits": [
      {
        ...
        "_source": {
          "field1": "dinner carrot potato broccoli",
          "field2": "something here",
          "lastseen": 1000
        }
      },
      {
        ...
        "_source": {
          "field1": "fish chicken something",
          "field2": "dinner",
          "lastseen": 2000
        }
      } 
   ]

更新1: 我尝试创建一个不lastseen包含在索引中的映射。这没有用。仍会取回所有4个结果。

curl -XPOST localhost:9200/myindex -d '{  
    "mappings": {
      "myobject": {
        "properties": {
          "lastseen": {
            "type": "long",
            "store": "yes",
            "include_in_all": false
          }
        }
      }
    }
}'

更新2: 我尝试使用此处列出的agg方案进行重复数据删除,但该方法不起作用,但更重要的是,我没有找到将其与关键字搜索结合的方法。


问题答案:

不理想,但是我认为它可以满足您的需求。

field1假设您是用来定义“重复”文档的字段,请更改字段的映射,如下所示:

PUT /lastseen
{
  "mappings": {
    "test": {
      "properties": {
        "field1": {
          "type": "string",
          "fields": {
            "raw": {
              "type": "string",
              "index": "not_analyzed"
            }
          }
        },
        "field2": {
          "type": "string"
        },
        "lastseen": {
          "type": "long"
        }
      }
    }
  }
}

意思是,您添加了一个.raw子字段,not_analyzed这意味着将按原样对它进行索引,而无需进行分析并将其分解为术语。这是为了使有些“重复的文档发现”成为可能。

然后,您需要在上使用terms聚合field1.raw(用于重复项)和top_hits子聚合,以获取每个field1值的单个文档:

GET /lastseen/test/_search
{
  "size": 0,
  "query": {
    "query_string": {
      "query": "dinner"
    }
  },
  "aggs": {
    "field1_unique": {
      "terms": {
        "field": "field1.raw",
        "size": 2
      },
      "aggs": {
        "first_one": {
          "top_hits": {
            "size": 1,
            "sort": [{"lastseen": {"order":"desc"}}]
          }
        }
      }
    }
  }
}

此外,传回的那个单一文件top_hits是最高的lastseen(可能使"sort": [{"lastseen": {"order":"desc"}}])。

您将获得的结果是这些(在aggregationsnot 之下hits):

   ...
   "aggregations": {
      "field1_unique": {
         "doc_count_error_upper_bound": 0,
         "sum_other_doc_count": 0,
         "buckets": [
            {
               "key": "dinner carrot potato broccoli",
               "doc_count": 2,
               "first_one": {
                  "hits": {
                     "total": 2,
                     "max_score": null,
                     "hits": [
                        {
                           "_index": "lastseen",
                           "_type": "test",
                           "_id": "AU60ZObtjKWeJgeyudI-",
                           "_score": null,
                           "_source": {
                              "field1": "dinner carrot potato broccoli",
                              "field2": "something here",
                              "lastseen": 1000
                           },
                           "sort": [
                              1000
                           ]
                        }
                     ]
                  }
               }
            },
            {
               "key": "fish chicken something",
               "doc_count": 2,
               "first_one": {
                  "hits": {
                     "total": 2,
                     "max_score": null,
                     "hits": [
                        {
                           "_index": "lastseen",
                           "_type": "test",
                           "_id": "AU60ZObtjKWeJgeyudJA",
                           "_score": null,
                           "_source": {
                              "field1": "fish chicken something",
                              "field2": "dinner",
                              "lastseen": 2000
                           },
                           "sort": [
                              2000
                           ]
                        }
                     ]
                  }
               }
            }
         ]
      }
   }


 类似资料:
  • 问题内容: 示例:存储在索引中的文档表示测试分数和有关每个测试的元数据。 我需要能够过滤掉除最低分数以外的所有分数,并为每个应试者返回与该测试相关的元数据。所以我的预期结果是: 我现在看到的唯一方法是,首先通过用户使用嵌套的最小聚合来进行术语聚合,以获得最低分。 然后,我必须获取该查询的结果,并对每个用户进行过滤查询,然后根据最低得分值进行过滤,以获取其余的元数据。Yu 我想知道是否有一种方法可以

  • 问题内容: 我已经在Elasticsearch之上构建了一个Web应用程序。我想使用Java进行多重过滤。 Elasticsearch查询: 我想过滤查询,以便它应该在具有两个不同值(例如“ xyz”和“ abc”)的同一字段上进行过滤 现在,我已经为单个过滤器编写了Java程序。 如何在同一字段上为多个值过滤查询? 编辑 : 实际上,在我的Web应用程序中,我将集合的值提取为: 收藏是我的Ela

  • 问题内容: “过滤后的查询和过滤器”与“根查询和过滤器”之间有什么区别吗?例如 情况1: 情况2: 我在http://elasticsearch-users.115913.n3.nabble.com/Filtered-query-vs-using- filter-outside-td3960119.html中 找到了此讨论,但所引用的URL是404,并且解释过于简洁我。 请示教或提供指出这些区别的

  • 我们的表有一个嵌套的映射角色,如下所示: 现在我要查找组123中在Department1中有角色的所有文档。如何基于嵌套映射的值字段进行筛选?类似于: 我知道如何通过嵌套对象键进行筛选,但无法找到通过“对象值”进行筛选。

  • 目前,我已经知道如何从(时间戳)日期字段中筛选日期范围。这是一个简单的问题: 但是,当你对基于时间的范围感兴趣时,如何过滤日期,比如gte:“8:00:00”和lte:“10:00:00”?这有可能吗? 换句话说,我的要求是:如何让所有事件在本月(15-11-01/15-11-30)发生,但只能在上午8:00到10:00之间发生?

  • 问题内容: 我需要按Field1的值对所有记录进行分组,并为每个组计算Field2的最大值。因此,有什么方法可以使最大聚合作用在同一查询中的多个组上? 问题答案: