elasticsearch - Elasticsearch 响应中嵌套对象的条件源过滤

标签 elasticsearch

我有一个具有以下(简化)结构的文档索引。

{
  "product_id": "abc123",
  "properties": [
    {
      "key": "width",
      "value": 1000
    },
    {
      "key": "height",
      "value": 2000
    },
    {
      "key": "depth",
      "value": 500
    }
  ]
}

每个文档可以具有数百个属性。

现在-我希望能够搜索与查询匹配的文档,并且还指定每个文档在返回时应填充的属性。所以基本上我想写以下请求:

Get me all documents that match query x, and populate each document with the properties ["height", "width", "foobar" ].



具有查询属性的数组是在查询时根据用户输入创建的。查询响应中的文档如下所示:
{
  "product_id": "abc123",
  "properties": [
    {
      "key": "width",
      "value": 1000
    },
    {
      "key": "height",
      "value": 2000
    }
    // No depth!
  ]
}

我试图通过源过滤来实现这一目标无济于事。我怀疑脚本字段可能是解决此问题的唯一方法,但我宁愿使用一些标准方法。任何人有任何想法吗?

最佳答案

我能想到的最好的方法是使用inner_hits。例如:

PUT proptest
{
  "mappings": {
    "default": {
      "properties": {
        "product_id": {
          "type": "keyword"
        },
        "color": {
          "type": "keyword"
        },
        "props": {
          "type": "nested"
        }
      }
    }
  }
}

PUT proptest/default/1
{
  "product_id": "abc123",
  "color": "red",
  "props": [
    {
      "key": "width",
      "value": 1000
    },
    {
      "key": "height",
      "value": 2000
    },
    {
      "key": "depth",
      "value": 500
    }
  ]
}
PUT proptest/default/2
{
  "product_id": "def",
  "color": "red",
  "props": [
  ]
}
PUT proptest/default/3
{
  "product_id": "ghi",
  "color": "blue",
  "props": [
    {
      "key": "width",
      "value": 1000
    },
    {
      "key": "height",
      "value": 2000
    },
    {
      "key": "depth",
      "value": 500
    }
  ]
}

现在我们可以通过color进行查询,并且仅获取heightdepthfoobar属性:
GET proptest/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "color": {
              "value": "red"
            }
          }
        },
        {
          "bool": {
            "should": [
              {
                "nested": {
                  "path": "props",
                  "query": {
                    "match": {
                      "props.key": "height depth foobar"
                    }
                  },
                  "inner_hits": {}
                }
              },
              {
                "match_all": {}
              }
            ]
          }
        }

      ]
    }
  },
 "_source": {
   "excludes": "props"
 }
} 

输出是
{
  "hits": {
    "total": 2,
    "max_score": 2.2685113,
    "hits": [
      {
        "_index": "proptest",
        "_type": "default",
        "_id": "1",
        "_score": 2.2685113,
        "_source": {
          "color": "red",
          "product_id": "abc123"
        },
        "inner_hits": {
          "props": {
            "hits": {
              "total": 2,
              "max_score": 0.9808292,
              "hits": [
                {
                  "_index": "proptest",
                  "_type": "default",
                  "_id": "1",
                  "_nested": {
                    "field": "props",
                    "offset": 2
                  },
                  "_score": 0.9808292,
                  "_source": {
                    "key": "depth",
                    "value": 500
                  }
                },
                {
                  "_index": "proptest",
                  "_type": "default",
                  "_id": "1",
                  "_nested": {
                    "field": "props",
                    "offset": 1
                  },
                  "_score": 0.9808292,
                  "_source": {
                    "key": "height",
                    "value": 2000
                  }
                }
              ]
            }
          }
        }
      },
      {
        "_index": "proptest",
        "_type": "default",
        "_id": "2",
        "_score": 1.287682,
        "_source": {
          "color": "red",
          "product_id": "def"
        },
        "inner_hits": {
          "props": {
            "hits": {
              "total": 0,
              "max_score": null,
              "hits": []
            }
          }
        }
      }
    ]
  }
}

请注意,结果包含已过滤正确属性的产品abc123def。产品abc123与给定的属性列表部分匹配,但def不包含任何属性。主要结果仅由外部查询color:red定义

该方法的缺点是无法在相同的顶级_source下但在内部hits键下找到属性。

关于elasticsearch - Elasticsearch 响应中嵌套对象的条件源过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55218577/

相关文章:

c# - 有什么方法可以将JSON查询转换为Elasticsearch Nest搜索查询吗?

elasticsearch - logstash始终只在我的索引中放置1个条目

Elasticsearch "starts with"短语中的第一个词

ruby-on-rails - Elasticsearch 控制台

elasticsearch - Elasticsearch - 将索引从集群导出到不同的集群

elasticsearch - 具有多个索引的 Elasticsearch 大小选项

php - Elasticsearch 和 Codeigniter (PHP)

elasticsearch - Elasticsearch:使用两个节点设置集群

java - Elasticsearch 传输客户端连接

elasticsearch - 查询匹配模式标记器