【问题标题】:Elastic search nested query - how to filter based only on first instance of nested document to answer filter弹性搜索嵌套查询 - 如何仅基于嵌套文档的第一个实例进行过滤以回答过滤器
【发布时间】:2019-08-11 21:22:36
【问题描述】:

我有一个包含对象数组的对象。 该数组被映射为嵌套。 假设数组是我多年来拥有的所有汽车的列表。

我希望能够搜索在特定时间点专门拥有“福特”的所有人。

我的数据只有汽车的“购买日期”。

假设我有一个人曾经有一辆福特,然后又换了一辆本田。

我的嵌套过滤器会说: “给我所有购买日期小于或等于‘特定时间点’并且他们的车型是‘福特’的人”

考虑到我的数据 - 我会让上面的人如实回答我的问题。

我想搜索与我的时间点相关的所有嵌套文档,然后仅查询最近的子文档以查看模型是否为福特。

这有可能吗?

谢谢!!!

【问题讨论】:

    标签: elasticsearch nested


    【解决方案1】:

    下面是示例映射、文档结构、您要查找的查询以及响应

    映射:

    PUT mycars
    {  
       "mappings":{  
          "properties":{  
             "cars":{  
                "type":"nested",
                "properties":{  
                   "purchase_date":{  
                      "type":"date"
                   },
                   "type":{  
                      "type":"text",
                      "fields":{  
                         "keyword":{  
                            "type":"keyword",
                            "ignore_above":256
                         }
                      }
                   }
                }
             },
             "owner":{  
                "type":"text",
                "fields":{  
                   "keyword":{  
                      "type":"keyword",
                      "ignore_above":256
                   }
                }
             }
          }
       }
    }
    

    如果您注意到映射,嵌套字段将是 cars,其中 purchase_date 作为日期字段,而 type 作为文本字段,同时提供文本和关键字类型。

    我还添加了一个字段owner,只是为了理解和赋予文档一种身份。

    示例文件:

    POST mycars/_doc/1
    {
      "owner": "john",
      "cars":[
        {
          "type": "Ford",
          "purchase_date": "2017-01-01"
        },
        {
          "type": "Tesla",
          "purchase_date": "2019-01-01"
        }
    
        ]
    }
    
    POST mycars/_doc/2
    {
      "owner": "jess",
      "cars":[
        {
          "type": "Ford",
          "purchase_date": "2017-01-01"
        }    
        ]
    }
    
    POST mycars/_doc/3
    {
      "owner": "jenny",
      "cars":[
        {
          "type": "Ford",
          "purchase_date": "2019-01-01"
        }
        ]
    }
    
    POST mycars/_doc/4
    {
      "owner": "tom",
      "cars":[
        {
          "type": "Ford",
          "purchase_date": "2016-01-01"
        }
        ]
    }
    

    现在您的查询是给我所有购买日期小于或等于“特定时间点”并且他们的型号是“福特”的人

    我有前两个和最后一个文档属于您的查询,日期为2017-01-01

    所以下面的查询是我所拥有的给了我所有在2018-01-01 或之前购买Ford 并且在2018-01-01 之后没有购买其他汽车的人

    查询:

    POST mycars/_search
    {
      "query": {
        "bool": {
          "must": [
            {
              "nested": {
                "path": "cars",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "match": {
                          "cars.type.keyword": "Ford"
                        }
                      },
                      {
                        "range": {
                          "cars.purchase_date": {
                            "lte": "2018-01-01"
                          }
                        }
                      }
                    ]
                  }
                }
              }
            }
          ],
          "must_not": [
          {
              "nested": {
                "path": "cars",
                "query": {
                  "bool": {
                    "must": [
                      {
                        "range": {
                          "cars.purchase_date": {
                            "gte": "2018-01-01"
                          }
                        }
                      }
                    ]
                  }
                }
              }
            }
          ]
        }
      }
    }
    

    我添加了must_not 子句,以便过滤用户在must 子句中提到的日期之后最终购买任何其他汽车的文档。

    请注意,我只是使用了Bool 查询和Range 查询嵌套文档。

    希望这会有所帮助!

    【讨论】:

    • 嗨!感谢您花时间回答我的问题。问题是约翰在 2017 年 1 月 7 日买了另一辆车,它是特斯拉。在这种情况下,截至 2018 年 1 月 1 日,他最近的汽车是特斯拉而不是福特。但是上面的查询会返回他的文档,因为他有一个嵌套文档,指定了上面的所有过滤器。
    • 当然。让我知道这是否是您正在寻找的。​​span>
    • 我正在寻找一种方法来找到他们在“特定日期”最近购买的汽车是福特的所有人。而不是在那个日期之前的某个时候买了一辆福特。这可能吗? (例如见上面的评论)
    • 请立即查看。我在最后添加了查询。
    • 哦,我现在明白你的问题了。不确定这在直接查询中是否可行,但让我看看我能做什么。
    猜你喜欢
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 2020-02-07
    • 2020-12-27
    • 1970-01-01
    相关资源
    最近更新 更多