You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elasticsearch嵌套数据文档无法精准过滤问题求助

无法对Elasticsearch中的嵌套数据文档执行精准过滤

我有一份嵌套格式的Elasticsearch文档,尝试通过嵌套查询仅返回attribute_id为40的产品,但实际返回了分类下的全部产品。分类数据由Laravel同步至Elasticsearch,最初以为是PHP端的数据问题,但通过Kibana控制台插入数据并验证mapping后,确认PHP发送的数据无异常。

映射(Mapping)结构

{
  "mappings": {
    "properties": {
      "attributes": {
        "properties": {
          "options": {
            "properties": {
              "attribute_id": {
                "type": "long"
              },
              "created_at": {
                "type": "long"
              },
              "id": {
                "type": "long"
              },
              "order": {
                "type": "long"
              },
              "updated_at": {
                "type": "long"
              },
              "value": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          },
          "title": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      },
      "id": {
        "type": "long"
      },
      "link": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "meta_description": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "meta_keywords": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "meta_title": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "name": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "position": {
        "type": "long"
      },
      "products": {
        "type": "nested",
        "properties": {
          "attributes": {
            "type": "nested",
            "properties": {
              "attribute_id": {
                "type": "integer"
              },
              "product_id": {
                "type": "integer"
              },
              "title": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "type": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "value": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          },
          "created_at": {
            "type": "date",
            "format": "YYY-MM-dd HH:mm:ss",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "en_name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "id": {
            "type": "integer"
          },
          "link": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "name": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "new": {
            "type": "boolean"
          },
          "new_from_date": {
            "type": "date",
            "format": "YYY-MM-dd HH:mm:ss",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "new_to_date": {
            "type": "date",
            "format": "YYY-MM-dd HH:mm:ss",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "order_count": {
            "type": "integer"
          },
          "price": {
            "type": "float"
          },
          "sku": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "special_from_date": {
            "type": "date",
            "format": "YYY-MM-dd HH:mm:ss",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "special_price": {
            "type": "integer"
          },
          "special_to_date": {
            "type": "date",
            "format": "YYY-MM-dd HH:mm:ss",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "view_count": {
            "type": "integer"
          },
          "whishlist_count": {
            "type": "integer"
          }
        }
      },
      "seo": {
        "properties": {
          "breadcrumbs": {
            "properties": {
              "@type": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "link": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "name": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              },
              "position": {
                "type": "long"
              },
              "url": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          },
          "metaDescription": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "metaTitle": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "meta_keywords": {
            "properties": {
              "value": {
                "type": "text",
                "fields": {
                  "keyword": {
                    "type": "keyword",
                    "ignore_above": 256
                  }
                }
              }
            }
          },
          "title": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      },
      "sort_order": {
        "type": "long"
      },
      "sortable": {
        "properties": {
          "id": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          },
          "title": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

Elasticsearch中存储的文档内容

{
  "id" : 5,
  "name" : "mobile",
  "link" : "/category/5/phone",
  "sort_order" : 1,
  "position" : 4,
  "seo" : {
    "title" : "mobile",
    "metaTitle" : "",
    "meta_keywords" : [
      {
        "value" : "phone"
      },
      {
        "value" : "mobile"
      }
    ],
    "metaDescription" : "",
    "description" : null,
    "breadcrumbs" : [
      {
        "@type" : "ListItem",
        "position" : 1,
        "name" : "home",
        "url" : "https://www.atramart.com/"
      },
      {
        "@type" : "ListItem",
        "position" : 2,
        "name" : "digitalproducts",
        "link" : "/category/5/phone"
      },
      {
        "@type" : "ListItem",
        "position" : 3,
        "name" : "phone",
        "link" : "/category/4/phone"
      },
      {
        "@type" : "ListItem",
        "position" : 4,
        "name" : "mobile",
        "link" : "/category/3/mobile"
      }
    ]
  },
  "products" : [
    {
      "id" : 1,
      "name" : "Xiaomi Black Shark 2 Pro Dual SIM SmartPhone",
      "sku" : "010002919100",
      "en_name" : "Xiaomi Black Shark 2 Pro Dual SIM SmartPhone - 128GB(12GB)",
      "new" : true,
      "new_from_date" : "2023-06-29 17:29:51",
      "new_to_date" : "2023-06-29 17:29:51",
      "price" : 4177739.0,
      "special_price" : 0,
      "special_from_date" : "2023-06-29 17:29:51",
      "special_to_date" : "2023-06-29 17:29:51",
      "link" : "/product/am-010002919100/Xiaomi Black Shark 2 Pro Dual SIM SmartPhone",
      "view_count" : 0,
      "whishlist_count" : 0,
      "order_count" : 0,
      "created_at" : "2023-06-29 12:33:58",
      "attributes" : [
        {
          "product_id" : 1,
          "attribute_id" : 26,
          "title" : "is_in_stock",
          "value" : "ins_stock",
          "type" : "select"
        },
        {
          "product_id" : 1,
          "attribute_id" : 40,
          "title" : "sim_count",
          "value" : "three",
          "type" : "select"
        }
      ]
    }
  ],
  "attributes" : [
    {
      "title" : "status",
      "options" : [
        {
          "id" : 3,
          "value" : "disable",
          "order" : 1,
          "attribute_id" : 10,
          "created_at" : "2023-06-29T09:03:37.000000Z",
          "updated_at" : "2023-06-29T09:03:37.000000Z"
        },
        {
          "id" : 4,
          "value" : "enable",
          "order" : 2,
          "attribute_id" : 10,
          "created_at" : "2023-06-29T09:03:37.000000Z",
          "updated_at" : "2023-06-29T09:03:37.000000Z"
        }
      ]
    }
  ],
  "banners" : null,
  "slider" : null,
  "sortable" : [
    {
      "id" : "_1",
      "title" : "new"
    },
    {
      "id" : "_2",
      "title" : "discount"
    },
    {
      "id" : "_3",
      "title" : "sellers"
    }
  ]
}

执行的查询语句

GET categories/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "id": 5
          }
        },
        {
          "nested": {
            "path": "products",
            "query": {
              "nested": {
                "path": "products.attributes",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "match": {
                          "products.attributes.attribute_id": 40
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      ]
    }
  }
}

问题分析与解决方案

你的查询已经能正确筛选出包含目标产品的分类文档,但默认情况下Elasticsearch会返回整个父文档(即完整的分类数据,包含所有产品),而非仅过滤后的产品。要只返回符合条件的产品,需要在嵌套查询中添加inner_hits参数,指定返回匹配的嵌套文档。

修正后的查询语句:

GET categories/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "id": 5
          }
        },
        {
          "nested": {
            "path": "products",
            "query": {
              "nested": {
                "path": "products.attributes",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "match": {
                          "products.attributes.attribute_id": 40
                        }
                      }
                    ]
                  }
                }
              }
            },
            "inner_hits": {} // 新增该参数,返回匹配的products文档
          }
        }
      ]
    }
  }
}

说明

  • inner_hits会在查询结果中单独生成一个inner_hits字段,包含所有匹配条件的products文档。
  • 外层的嵌套查询针对products路径,内层嵌套查询针对products.attributes路径,符合你的双层嵌套结构,逻辑是正确的。
  • 如果需要完全替换返回的文档结构,只保留匹配的产品,可以结合source filtering或使用collapse功能,但inner_hits是最直接获取匹配嵌套文档的方式。

内容的提问来源于stack exchange,提问作者opsource

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 13:04:52