ElasticSearch:对象数组内的高级搜索

ubbxdtey  于 2023-06-21  发布在  ElasticSearch
关注(0)|答案(1)|浏览(148)

假设我在Elasticsearch中存储了以下文档:

{
  id: '349dec5f-4ddf-4faa-beb0-79a0ea08bad6',
  name: 'Iphone 13',
  criteria: [
    {
      name: 'color',
      options: ['Midnight', 'Blue', 'Green'],
    },
  ]
},
{
  id: '1a63de5a-4335-4e0d-83ab-c820d57709bd',
  name: 'IPhone 14',
  criteria: [
    {
      name: 'color',
      options: ['Midnight', 'Purple', 'Red'],
    },
    {
      name: 'size',
      options: ['128GB', '256GB'],
    },
  ]
},
{
  id: 'eae5672f-2153-4f7d-be68-122e6d9fe5e1',
  name: 'Iphone 14 Pro',
  criteria: [
    {
      name: 'color',
      options: ['Black', 'Blue', 'Red'],
    },
    {
      name: 'size',
      options: ['64GB', '128GB', '256GB'],
    },
  ]
}

我为这些文档创建了以下类型Map:

"properties": {
  "id": { "type": "keyword", "ignore_above": 36 },
  "name": { "type": "text" },
  "category": { "type": "keyword", "ignore_above": 36 },
  "criteria": {
    "type": "nested",
    "properties": {
      "name": { "type": "keyword", "ignore_above": 500 },
      "options": { "type": "keyword", "ignore_above": 500 }
    }
  }
}

注意,criteria是一个嵌套的对象数组,有两个字段criteria.namecriteria.options,所以它不仅可以有colorsize,还可以有其他值。
我想通过特定的colorsize过滤这些文档,例如,当我在HTTP请求中获得以下filter对象时:

{
  search: null,
  filter: {
    criteria: [
      {
        name: 'color',
        options: ['Blue', 'Red'],
        operator: 'OR'
      },
      {
        name: 'size',
        options: ['64GB', '128GB'],
        operator: 'OR'
      }
    ]
  }
}

我需要获取具有'Blue''Red'颜色和'64GB''128GB'大小的文档,因此,它看起来像这样:

if criteria.name == 'color' THEN
  criteria.options should include one of ['Blue', 'Red']
if criteria.name == 'size' THEN
  criteria.options should include one of ['64GB', '128GB']

因此,例如,对于上面的响应中的filter对象,我应该返回两个文档,第一个是name: 'IPhone 14',第二个是name: 'Iphone 14 Pro',因为第一个是第一个(name: 'IPhone 14')具有“红色”颜色和“128GB”大小,第二个(name: 'Iphone 14 Pro')具有“蓝色”和“红色”颜色以及“64GB”和“128GB”大小。
那么,我的问题是如何实现这一点?

dluptydi

dluptydi1#

尝试使用Nested Queries

{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "criteria",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "criteria.name": "color"
                    }
                  }
                ], 
                "filter": [
                  {
                    "terms": {
                      "criteria.options": [
                        "Blue",
                        "Red"
                      ]
                    }
                  }
                ]
              }
            }
          }
        },
        {
          "nested": {
            "path": "criteria",
            "query": {
              "bool": {
                "must": [
                  {
                    "match": {
                      "criteria.name": "size"
                    }
                  }
                ], 
                "filter": [
                  {
                    "terms": {
                      "criteria.options": [
                        "64GB",
                        "128GB"
                      ]
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

相关问题