从数组结果中删除项目

时间:2017-01-13 15:52:39

标签: elasticsearch

我有这个结果

 {
    "_index": "products-1479727033119",
    "_type": "product",
    "_id": "123",
    "_score": 5.2519913,
    "_source": {
      "name": "Samsung S7",
      "rating": 4.5123123,
      "id": "609126",
      "stores": [
        {
            "id" :123214,
            "name":"Walmart"
        },
        {
            "id" :2141251,
            "name":"ebay"
        }
      ],
    }
  }

在某些情况下,我需要我的结果相同,但我需要过滤数组项

结果应该是这样的:

{
    "_index": "products-1479727033119",
    "_type": "product",
    "_id": "123",
    "_score": 5.2519913,
    "_source": {
      "name": "Samsung S7",
      "rating": 4.5123123,
      "id": "609126",
      "stores": [
        {
            "id" :123214,
            "name":"Walmart"
        }
      ],
    }
  }

这可以在一个查询中实现吗?

1 个答案:

答案 0 :(得分:0)

是的,您必须查看elasticsearch中的嵌套对象。您必须在架构中为嵌套对象定义映射。设置架构以支持源文档中的嵌套对象后,可以使用嵌套过滤器,内部命令。

为您的文档使用以下架构映射。

-XPut "localhost:9200/products/product/_mapping"
    {
        "product": {
            "_source": {
                "enabled": true
            },
            "properties": {
                "stores": {
                    "type": "nested",
                    "properties": {
                        "id": {
                            "type": "string",
                            "index": "analyzed"
                        },
                        "name": {
                            "type": "string",
                            "index": "analyzed"
                        }
                    }
                },
                "name": {
                    "type": "string",
                    "index": "analyzed"
                },

                "rating": {
                    "type": "integer"
                },
                "id": {
                    "type": "integer"
                }
            }
        }
    }

现在您的用例可能包括也可能不包括过滤父文档,但由于您基本上需要过滤嵌套文档以匹配某些条件,因此您可以使用嵌套过滤器/查询内部命令。 elasticsearch中的Innerhits返回一个文档中的内部嵌套文档与嵌套查询匹配。

让我们假设两种情况 -

a)不过滤父文件 -

{
    "query": {
        "filtered": {
            "query": {
                "bool": {
                    "must": [{
                        "nested": {
                            "path": "stores",
                            "query": {
                                "filtered": {
                                    "query": {
                                        "bool": {
                                            "must": [{
                                                "term": {
                                                    "stores.name": {
                                                        "value": "nokia"
                                                    }
                                                }
                                            }]
                                        }
                                    }
                                }
                            },
                            "inner_hits":{}
                        }
                    }]
                }
            }
        }
    }
}

b)过滤父对象和嵌套对象 -

{
    "query": {
        "filtered": {
            "query": {
                "bool": {
                    "must": [
                      {"term": {
                        "name": {
                          "value": "samsung"
                        }
                      }},
                      {
                        "nested": {
                            "path": "stores",
                            "query": {
                                "filtered": {
                                    "query": {
                                        "bool": {
                                            "must": [{
                                                "term": {
                                                    "stores.name": {
                                                        "value": "nokia"
                                                    }
                                                }
                                            }]
                                        }
                                    }
                                }
                            },
                            "inner_hits":{}
                        }
                    }]
                }
            }
        }
    }
}

如果是b,您也可以在父文档上使用过滤器。

Innerhits响应 -

   {
  "took": 6,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 2.122635,
    "hits": [
      {
        "_index": "nested",
        "_type": "product",
        "_id": "AVmYrzR0isULrG9L5jlr",
        "_score": 2.122635,
        "_source": {
          "name": "Samsung S7",
          "rating": 4.5123123,
          "id": "609126",
          "stores": [
            {
              "id": 123214,
              "name": "Walmart"
            },
            {
              "id": 898989,
              "name": "nokia"
            },
            {
              "id": 67676,
              "name": "nokia"
            }
          ]
        },
        "inner_hits": {
          "stores": {
            "hits": {
              "total": 2,
              "max_score": 1.8472979,
              "hits": [
                {
                  "_index": "nested",
                  "_type": "product",
                  "_id": "AVmYrzR0isULrG9L5jlr",
                  "_nested": {
                    "field": "stores",
                    "offset": 2
                  },
                  "_score": 1.8472979,
                  "_source": {
                    "id": 67676,
                    "name": "nokia"
                  }
                },
                {
                  "_index": "nested",
                  "_type": "product",
                  "_id": "AVmYrzR0isULrG9L5jlr",
                  "_nested": {
                    "field": "stores",
                    "offset": 1
                  },
                  "_score": 1.8472979,
                  "_source": {
                    "id": 898989,
                    "name": "nokia"
                  }
                }
              ]
            }
          }
        }
      }
    ]
  }
}

正如你在响应对象中看到的那样,inner_hits会出现一个额外的json对象以及源文档,innerhits json对象包含一个与“nokia”匹配的所有已过滤嵌套文档的数组。

您确实得到了您提出的格式/数据结构。您可以稍后编写API层转换器,模型序列化器将响应解析为您希望客户端(浏览器/应用程序)所需的格式

请参阅elastic innerhits doc以获取更多参考资料。

希望这会有所帮助 感谢