3

弹性搜索版本:7.6.2

我在下面有以下简化的结构和查询。

PUT /products
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text"
      },
      "description": {
        "type": "text"
      },
      "variants": {
        "type": "nested",
        "include_in_parent": true,
        "properties": {
          "price": {
            "type": "double"
          },
          "tags": {
            "type": "text"
          }
        }
      }
    }
  }
}

PUT /products/_doc/1?refresh
{
    "name": "Product Pizza",
    "description": "Product Pizza Description",
    "variants": [
        { "price": 100, "tags": ["capri", "small", "noketchup"] },
        { "price": 110, "tags": ["capri", "medium", "ketchup"] },
        { "price": 300, "tags": ["capri", "medium", "noketchup"] },
        { "price": 210, "tags": ["vege", "medium", "ketchup"] },
        { "price": 220, "tags": ["vege", "medium", "noketchup"] },
        { "price": 330, "tags": ["vege", "large", "ketchup"] }
    ]
}


PUT /products/_doc/2?refresh
{
  "name": "Product Towel",
  "description": "Product Towel Description",
  "variants": [
    { "price": 50, "tags": ["blue", "small"] },
    { "price": 60, "tags": ["blue","medium"] },
    { "price": 70, "tags": ["blue","large"] },
    { "price": 55, "tags": ["red","small"] },
    { "price": 65, "tags": ["red","medium"] },
    { "price": 75, "tags": ["red","large"] }
  ]
}


GET /products/_search
{
  "track_scores": true,
  "query": {
    "nested": {
      "path": "variants",
      "inner_hits": {
        "size": 10
      },
      "query": {
        "multi_match": {
          "query": "vege medium",
          "operator": "or",
          "fields": [
            "variants.tags"
          ]
        }
      }
    }
  },
  "sort": [
    {
      "variants.price": {
        "mode": "min",
        "nested": {
          "filter": {
            "multi_match": {
              "query": "vege medium",
              "operator": "or",
              "fields": [
                "variants.tags"
              ]
            }
          },
          "path": "variants"
        },
        "order": "asc"
      }
    }
  ]
}

我需要实现的是以某种方式获得最佳匹配的嵌套结果,然后从该嵌套变体中获取价格字段。

  1. 按最低价格排序时,排序应为第一个产品返回 210,为第二个产品返回 60
  • 匹配两个标签“vege”“medium”
  1. 按最高价格排序时,排序应为第一个产品返回 220,为第二个产品返回 65
  • 匹配一个标签“中”

我尝试了几件事

  1. 对 multi_match 使用“and”而不是“or”,但第二个产品会从结果中排除。
  2. 使用 max_children 进行嵌套排序,但它只需要数组中的第一个嵌套(过滤后,它不会按分数对它们进行排序)。
  3. 在执行 max_children 之前,我检查了是否可以按分数对嵌套变体进行排序,显然不是。

任何建议表示赞赏,这不是最终结构,因此也欢迎任何改变结构的想法。

这样的事情是如何实现的,也许是使用脚本?

4

0 回答 0