简体   繁体   English

使用弹性搜索的自定义构面

[英]Custom facets using Elastic Search

I have a search page that uses facets.我有一个使用构面的搜索页面。 When a user enters terms in the search bar or selects a facet checkbox on the left hand column, this triggers a new search in our Elastic Search index.当用户在搜索栏中输入术语或选择左侧列中的一个方面复选框时,这会在我们的 Elastic Search 索引中触发新搜索。 在此处输入图片说明

Here is how the facets work.以下是切面的工作方式。 Our query includes an aggregation on each of the facet categories.我们的查询包括对每个方面类别的聚合。 For example, the aggregation response for the firstname category includes all first names from the result set and the number of times each name appears in the result set.例如,名字类别的聚合响应包括结果集中的所有名字以及每个名字在结果集中出现的次数。 As this is a Vuejs app and the facet data is a responsive variable, the facet then updates with the new list of keys and document counts in parenthesis.由于这是一个 Vuejs 应用程序,并且构面数据是一个响应变量,因此构面会使用括号中的新键列表和文档计数进行更新。

在此处输入图片说明

This is problematic, because a user can only select a single checkbox in each facet.这是有问题的,因为用户只能在每个方面选择一个复选框。 As soon as the user selects a checkbox, the other options disappear because the new result set and aggregation response now are restricted to documents that satisfy the selected checkbox.一旦用户选择一个复选框,其他选项就会消失,因为新的结果集和聚合响应现在仅限于满足所选复选框的文档。

I think what I need to do is customize my aggregation, but I can be wrong and there is a simpler or smarter approach.我认为我需要做的是自定义我的聚合,但我可能是错的,有一个更简单或更聪明的方法。 Let me know if that is the case.如果是这种情况,请告诉我。

I imagine I need to refactor so that when a user selects a checkbox in category foo, the aggregation operates on a different result set that takes into account the search bar term and the checked values in all other categories, but ignores the user's selections in the foo category.我想我需要重构,以便当用户选择类别 foo 中的复选框时,聚合在不同的结果集上运行,该结果集考虑了搜索栏术语和所有其他类别中的选中值,但忽略用户在foo 类。 How can this be done in Elastic?这如何在 Elastic 中完成?

A requirement is that selecting a checkbox immediately triggers a new search to update the table and the content of the other facet categories.一个要求是选择复选框会立即触发新搜索以更新表格和其他构面类别的内容。

Ultimately, I need to implement this with Elastic's high level REST client for JAVA, but even just cURL examples would be helpful.最终,我需要使用 Elastic 的 JAVA 高级 REST 客户端来实现这一点,但即使只是 cURL 示例也会有所帮助。

Here is my current aggregation query...这是我当前的聚合查询...

        for (String colName : colNames) {
        sourceBuilder.aggregation(AggregationBuilders.terms(colName)
                .field(colName + ".keyword"));
    }

If I am understanding your question right, you want your terms aggregation to be independent of search query.如果我正确理解您的问题,您希望您的术语聚合独立于搜索查询。

You can use global aggregation for it.您可以对其使用全局聚合

Defines a single bucket of all the documents within the search execution context.定义搜索执行上下文中所有文档的单个存储桶。 This context is defined by the indices and the document types you're searching on, but is not influenced by the search query itself此上下文由您搜索的索引和文档类型定义,但不受搜索查询本身的影响

Example例子

Mapping:映射:

{
  "index50" : {
    "mappings" : {
      "properties" : {
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    }
  }

Data:数据:

 "hits" : [
      {
        "_index" : "index50",
        "_type" : "_doc",
        "_id" : "v8MR3XABAqtoal9HOsoo",
        "_score" : 1.0,
        "_source" : {
          "name" : "john"
        }
      },
      {
        "_index" : "index50",
        "_type" : "_doc",
        "_id" : "wMMR3XABAqtoal9HU8rs",
        "_score" : 1.0,
        "_source" : {
          "name" : "doe"
        }
      }
    ]

Query:询问:

{
  "query": {
    "match": {
      "name": "john"
    }
  },
  "aggs": {
    "name_global_faucet": {
      "global": {},--> will return terms from all documents
      "aggs": {
        "first_name": {
          "terms": {
            "field": "name.keyword",
            "size": 10
          }
        }
      }
    },
    "name_faucet": {
      "terms": {--> will return terms from documents returned in query
        "field": "name.keyword",
        "size": 10
      }
    }
  }
}

Result:结果:

  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.6931472,
    "hits" : [
      {
        "_index" : "index50",
        "_type" : "_doc",
        "_id" : "v8MR3XABAqtoal9HOsoo",
        "_score" : 0.6931472,
        "_source" : {
          "name" : "john"
        }
      }
    ]
  },
  "aggregations" : {
    "name_faucet" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "john",
          "doc_count" : 1
        }
      ]
    },
    "name_global_faucet" : {
      "doc_count" : 2,
      "first_name" : {
        "doc_count_error_upper_bound" : 0,
        "sum_other_doc_count" : 0,
        "buckets" : [
          {
            "key" : "doe",
            "doc_count" : 1
          },
          {
            "key" : "john",
            "doc_count" : 1
          }
        ]
      }
    }
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM