当前位置: 首页 > 知识库问答 >
问题:

如何在Elasticsearch中以编程方式创建筛选查询,并在嵌套对象中进行筛选

商飞尘
2023-03-14

我正忙于在Java Spring中为ElasttiSearch创建过滤查询。我有以下Elasticsearch映射:

"mappings": {
  "properties": {
    "id": {"type": "keyword"},
    "name": {"type": "text"},
    "city": {"type": "keyword"},
    "cars": {
      "type": "nested",
      "properties": {
        "id": {"type": "long"},
        "brand": {"type": "text"},
        "category": {"type": "text"}
      }
   }
}

Elasticsearch中的数据如下所示:

[
   {
      "id": 1,
      "name": "Car seller 1",
      "city": "Detroit",
      "cars": [
         {"id": 1, "brand": "bmw", "category": "suv"},
         {"id": 2, "brand": "bmw", "category": "sedan"},
         {"id": 3, "brand": "bmw", "category": "hatchback"}
      ]
   },
   {
      "id": 2,
      "name": "Car seller 2",
      "city": "Detroit",
      "cars": [
         {"id": 1, "brand": "vw", "category": "suv"},
         {"id": 2, "brand": "vw", "category": "sedan"},
         {"id": 3, "brand": "vw", "category": "suv"}
      ]
   },
   {
      "id": 3,
      "name": "Car seller 3",
      "city": "Las Vegas",
      "cars": [
         {"id": 1, "brand": "ford", "category": "suv"},
         {"id": 2, "brand": "ford", "category": "sedan"},
         {"id": 3, "brand": "ford", "category": "hatchback"}
      ]
   }
]
 1. city: ["Detroit"]
 2. cars.category: ["suv"]
[
   {
      "id": 1,
      "name": "Car seller 1",
      "city": "Detroit",
      "cars": [
         {"id": 1, "brand": "bmw", "category": "suv"}
      ]
   },
   {
      "id": 2,
      "name": "Car seller 2",
      "city": "Detroit",
      "cars": [
         {"id": 1, "brand": "vw", "category": "suv"},
         {"id": 3, "brand": "vw", "category": "suv"}
      ]
   }
]
    public Flux<Seller> filterSearch(Map<String, List<String>> filters) {

      List<String> listOfFields = new ArrayList<>(filters.keySet());
      BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

      listOfFields.forEach(field -> {
          BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

          if (field.contains("cars.")) {
              filters.get(field).forEach(value -> boolQueryBuilder.should(QueryBuilders.termQuery(field, value)));
              boolQueryBuilder.minimumShouldMatch(1);
              NestedQueryBuilder nestedQueryBuilder = new NestedQueryBuilder("cars", boolQueryBuilder, NestedQueryBuilder.parseScoreMode("none"));
              nestedQueryBuilder.innerHit(new InnerHitBuilder());
              queryBuilder.must().add(nestedQueryBuilder);
          } else {
              filters.get(field).forEach(value -> boolQueryBuilder.should(QueryBuilders.matchPhraseQuery(field, value)));
              queryBuilder.must().add(boolQueryBuilder);
          }
      });

      return executeSearchQuery(queryBuilder);
   }

共有1个答案

刘野
2023-03-14

我想你应该试试这个:

      if (field.contains("cars.")) {
          ...
      } else {
          filters.get(field).forEach(value -> boolQueryBuilder.should(QueryBuilders.matchPhraseQuery(field, value)).minimumShouldMatch(1));
          queryBuilder.must().add(boolQueryBuilder);
      }
 类似资料:
  • 我是Elasticsearch的新手,我试图创建一个过滤器来检索具有特定属性的文档。 属性在映射中定义为嵌套对象,如下所示: 我试图以以下形式执行一个复杂的查询: 这是elasticsearch 2.x。我做错了什么?

  • 好吧,这一个对你们中的一个超级棒的弹性搜索专家来说可能不会太难。我得到了这个嵌套查询,我希望嵌套查询在一个非嵌套字段(状态)上进行过滤。我不知道把过滤器放在哪里。我试着把它放在一个查询中(如下),但没有给出正确的结果。你能帮我吗?

  • 我的映射如下所示,我正在对名称和其他属性进行bool应该查询,如下所示,但我需要的是,我希望在响应时根据CustomerId过滤CustomerPrices。每个产品都有相同的CustomerID,所以Eaxample; 因此,根据我查询Product1时,响应应该只有CustomerId:1234的customerPrice 我尝试了以下查询,但这不是过滤嵌套对象。我想它过滤产品对象是有意义的,

  • 我试图在嵌套筛选器聚合中使用嵌套查询筛选器。当我这样做时,聚合返回时没有任何项。如果我将查询更改为简单的旧match_all筛选器,我确实会在bucket中获得项。 下面是我正在使用的映射的简化版本: 该查询在聚合上使用match_all筛选器:

  • 示例文档 索引定义 内部无源过滤的响应良好。 响应包含嵌套属性的所有属性。即开始时间、结束时间和文本行。如何在响应中仅返回endtime和startTime? 查询失败 错误HTTP/1.1 400错误请求内容类型:application/json;字符集=UTF-8内容长度:265 {"错误":{"root_cause":[{"type":"illegal_argument_exception"

  • 我试图创建一个安全过滤器,以排除某些用户在ElasticSearch中看到某些文档。例如,如果一个文档包含“abc:123”和“abc:xyz”,那么用户的配置文件中必须同时包含这两个文档才能查看该文档。我们正在使用小胡子模板创建这个动态。我的第一次尝试是这样的: 但是,我很快意识到,这将允许拥有一个控件的用户查看具有多个控件的文档。文档必须具有用户必须匹配的控件的子集。因此,如果用户只有“abc