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

huangapple go评论71阅读模式
英文:

ElasticSearch: advanced search inside the array of objects

问题

你想要实现的目标是基于特定的颜色和尺寸筛选Elasticsearch中的文档。你可以使用布尔查询和嵌套过滤来实现这一目标。

以下是一个示例的Elasticsearch查询:

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

这个查询使用了布尔查询来组合多个条件,首先进入嵌套的 criteria 对象,然后分别检查颜色和尺寸是否匹配指定的选项。这将返回符合条件的文档。

请注意,上述查询是基于你提供的数据结构和要过滤的条件而创建的示例查询,你可以根据自己的需求进行修改。希望这能帮助你实现你的目标。

英文:

Let's assume that I have the following documents stored in 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'],
    },
  ]
}

And I have the following type mappings for these documents:

"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 }
    }
  }
}

Note that criteria is a nested array of objects with two fields criteria.name and criteria.options, so it can have not only color and size, but other values as well.

And I want to filter these documents by particular color and size, for example, when I get the following filter object in an HTTP request:

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

I need to get documents that have 'Blue' or 'Red' color AND '64GB' OR '128GB' size, so, it looks something like this:

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']

So, for example, for the above filter object in the response, I should return two documents, the first with name: 'IPhone 14' and the second with name: 'Iphone 14 Pro' because the first one (name: 'IPhone 14') has a "Red" color and a size of "128GB", and the second (name: 'Iphone 14 Pro') has both "Blue" and "Red" colors and both "64GB" and "128 GB" sizes.

So, my question is how to achieve this?

答案1

得分: 1

请尝试使用嵌套查询

{
  "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"
                      ]
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}
英文:

Try use 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"
                      ]
                    }
                  }
                ]
              }
            }
          }
        }
      ]
    }
  }
}

huangapple
  • 本文由 发表于 2023年6月15日 00:56:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76475921.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定