繁体   English   中英

Elasticsearch 多级嵌套查询

[英]Elasticsearch multi level nested query

具有多级嵌套字段的映射,如下所示:

{
  otherFields....,
  nestedField: {
    type: "nested",
    include_in_parent: true,
    multiple: true,
    properties: {
      province: {
        type: "nested",
        include_in_parent: true,
        multiple: true
      },
      properties: {
        comuni: {
          type: "nested",
          include_in_parent: true,
          multiple: true,
          properties: {
            nome: {
              type: "string"
            },
            parziale: {
              type: "boolean"
            }
          }
        },
        nome: {
          type: "string"
        }
      }
    }
  },
  regione: {
    type: "string"
  }
}

文档提到可以在此字段上执行查询https://www.elastic.co/guide/en/elasticsearch/reference/1.7/query-dsl-nested-query.html

使用此查询:

{
  "size": 1,
  "version": true,
  "query": {
    "filtered": {
      "query": {
        "function_score": {
          "query": {
            "bool": {
              "must": [
                {
                  "regex_term": {
                    "field_2": {
                      "term": ".*701.*",
                      "ignorecase": true
                    }
                  }
                }
              ]
            }
          },
          "functions": [
            {
              "script_score": {
                "script": "_score * -doc['field_2'].value.length()"
              }
            }
          ]
        }
      },
      "filter": {
        "nested": {
          "path": "nestedField",
          "filter": {
            "bool": {
              "must": [
                {
                  "term": {
                    "nestedField.regione": "Lazio"
                  }
                },
                {
                  "bool": {
                    "must": [
                      {
                        "or": {
                          "filters": [
                            {
                              "term": {
                                "nestedField.province.nome": "Pordenone"
                              }
                            },
                            {
                              "not": {
                                "filter": {
                                  "exists": {
                                    "field": "nestedField.province.nome"
                                  }
                                }
                              }
                            }
                          ]
                        }
                      },
                      {
                        "or": {
                          "filters": [
                            {
                              "term": {
                                "nestedField.province.comuni.nome": "Udine"
                              }
                            },
                            {
                              "not": {
                                "filter": {
                                  "exists": {
                                    "field": "nestedField.province.comuni.nome"
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

函数分数部分看起来不错,但在嵌套过滤器部分都存在一些问题。 数据如下所示:

{
  "_source": {
    "otheFields" ...,
    "nestedField": [
      {
        "regione": "Lazio"
      },
      {
        "province": [
          {
            "nome": "Venezia"
          },
          {
            "nome": "Treviso"
          }
        ],
        "regione": "Veneto"
      },
      {
        "province": [
          {
            "comuni": [
              {
                "nome": "Varmo",
                "parziale": false
              }
            ],
            "nome": "Udine"
          }
        ],
        "regione": "Friuli venezia giulia"
      }
    ]
  }
}

即使省字段丢失,查询也不会找到给定的记录,相反,如果我们对 regione 使用“Veneto”,对 provincia.nome 使用“Treviso”,并在另一个嵌套对象中使用 comune 字段,则它可以正常工作。

为什么这个查询不起作用?

尝试将您的条款更改为小写。 由于您没有在映射中指定分析器,因此使用标准分析器,它将术语转换为小写。

您的查询非常复杂,起初我以为您可能需要更多"nested"子句,但是当我执行以下操作时,它似乎有效。 (我确实很快就完成了这个,所以如果我在这里展示的内容由于某种原因对你不起作用,请告诉我。)

我不得不"regex_term" "query"部分,因为我在"regex_term"上遇到错误,但如果我"regex_term" ,如果我们只有一个文档,应该不会影响结果。

所以我创建了一个这样的索引(在"province"的定义之后,你的一个大括号在错误的地方):

PUT /test_index
{
   "settings": {
      "number_of_shards": 1
   },
   "mappings": {
      "doc": {
         "properties": {
            "nestedField": {
               "type": "nested",
               "include_in_parent": true,
               "multiple": true,
               "properties": {
                  "province": {
                     "type": "nested",
                     "include_in_parent": true,
                     "multiple": true,
                     "properties": {
                        "comuni": {
                           "type": "nested",
                           "include_in_parent": true,
                           "multiple": true,
                           "properties": {
                              "nome": {
                                 "type": "string"
                              },
                              "parziale": {
                                 "type": "boolean"
                              }
                           }
                        },
                        "nome": {
                           "type": "string"
                        }
                     }
                  }
               },
               "regione": {
                  "type": "string"
               }
            }
         }
      }
   }
}

添加了您的文档:

PUT /test_index/doc/1
{
   "nestedField": [
      {
         "regione": "Lazio"
      },
      {
         "province": [
            {
               "nome": "Venezia"
            },
            {
               "nome": "Treviso"
            }
         ],
         "regione": "Veneto"
      },
      {
         "province": [
            {
               "comuni": [
                  {
                     "nome": "Varmo",
                     "parziale": false
                  }
               ],
               "nome": "Udine"
            }
         ],
         "regione": "Friuli venezia giulia"
      }
   ]
}

然后运行这个修改后的查询:

POST /test_index/_search
{
   "size": 1,
   "version": true,
   "query": {
      "filtered": {
         "filter": {
            "nested": {
               "path": "nestedField",
               "filter": {
                  "bool": {
                     "must": [
                        {
                           "term": {
                              "nestedField.regione": "lazio"
                           }
                        },
                        {
                           "bool": {
                              "must": [
                                 {
                                    "or": {
                                       "filters": [
                                          {
                                             "term": {
                                                "nestedField.province.nome": "pordenone"
                                             }
                                          },
                                          {
                                             "not": {
                                                "filter": {
                                                   "exists": {
                                                      "field": "nestedField.province.nome"
                                                   }
                                                }
                                             }
                                          }
                                       ]
                                    }
                                 },
                                 {
                                    "or": {
                                       "filters": [
                                          {
                                             "term": {
                                                "nestedField.province.comuni.nome": "udine"
                                             }
                                          },
                                          {
                                             "not": {
                                                "filter": {
                                                   "exists": {
                                                      "field": "nestedField.province.comuni.nome"
                                                   }
                                                }
                                             }
                                          }
                                       ]
                                    }
                                 }
                              ]
                           }
                        }
                     ]
                  }
               }
            }
         }
      }
   }
}

文件被退回:

{
   "took": 4,
   "timed_out": false,
   "_shards": {
      "total": 1,
      "successful": 1,
      "failed": 0
   },
   "hits": {
      "total": 1,
      "max_score": 1,
      "hits": [
         {
            "_index": "test_index",
            "_type": "doc",
            "_id": "1",
            "_version": 1,
            "_score": 1,
            "_source": {
               "nestedField": [
                  {
                     "regione": "Lazio"
                  },
                  {
                     "province": [
                        {
                           "nome": "Venezia"
                        },
                        {
                           "nome": "Treviso"
                        }
                     ],
                     "regione": "Veneto"
                  },
                  {
                     "province": [
                        {
                           "comuni": [
                              {
                                 "nome": "Varmo",
                                 "parziale": false
                              }
                           ],
                           "nome": "Udine"
                        }
                     ],
                     "regione": "Friuli venezia giulia"
                  }
               ]
            }
         }
      ]
   }
}

这是所有代码集中在一处:

http://sense.qbox.io/gist/3b187e0fe22651a42501619ff867e02501b81f9e

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM