简体   繁体   English

Elasticsearch 多级嵌套查询

[英]Elasticsearch multi level nested query

Having a mapping with multi level nested fields like this:具有多级嵌套字段的映射,如下所示:

{
  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"
  }
}

the documentation mentions that is possible to perform a query on this field https://www.elastic.co/guide/en/elasticsearch/reference/1.7/query-dsl-nested-query.html .文档提到可以在此字段上执行查询https://www.elastic.co/guide/en/elasticsearch/reference/1.7/query-dsl-nested-query.html

Using this query:使用此查询:

{
  "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"
                                  }
                                }
                              }
                            }
                          ]
                        }
                      }
                    ]
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

the function score part looks good but both have some issues in the nested filter part.函数分数部分看起来不错,但在嵌套过滤器部分都存在一些问题。 The data look like this:数据如下所示:

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

The query doesn't find the given record even if the province field is missing, instead it work fine if we use "Veneto" for regione and "Treviso" for provincia.nome and also using the comune field in the other nested object.即使省字段丢失,查询也不会找到给定的记录,相反,如果我们对 regione 使用“Veneto”,对 provincia.nome 使用“Treviso”,并在另一个嵌套对象中使用 comune 字段,则它可以正常工作。

Why this query doesn't work ?为什么这个查询不起作用?

Trying changing your terms to lower-case.尝试将您的条款更改为小写。 Since you don't specify an analyzer in your mapping, the standard analyzer is used, which will convert terms to lower-case.由于您没有在映射中指定分析器,因此使用标准分析器,它将术语转换为小写。

Your query is pretty involved, and at first I thought you might need more "nested" clauses, but when I did the following, it seemed to work.您的查询非常复杂,起初我以为您可能需要更多"nested"子句,但是当我执行以下操作时,它似乎有效。 (I did go through this pretty quickly, so let me know if what I've shown here doesn't work for you for some reason.) (我确实很快就完成了这个,所以如果我在这里展示的内容由于某种原因对你不起作用,请告诉我。)

I had to take out the "query" part since I got an error on "regex_term" , but if I'm reading it right that shouldn't affect the outcome if we only have the one document.我不得不"regex_term" "query"部分,因为我在"regex_term"上遇到错误,但如果我"regex_term" ,如果我们只有一个文档,应该不会影响结果。

So I created an index like this (one of your braces was in the wrong place, after the definition of "province" ):所以我创建了一个这样的索引(在"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"
               }
            }
         }
      }
   }
}

added your doc:添加了您的文档:

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"
      }
   ]
}

Then ran this modified query:然后运行这个修改后的查询:

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"
                                                   }
                                                }
                                             }
                                          }
                                       ]
                                    }
                                 }
                              ]
                           }
                        }
                     ]
                  }
               }
            }
         }
      }
   }
}

and the document was returned:文件被退回:

{
   "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"
                  }
               ]
            }
         }
      ]
   }
}

Here's all the code in one place:这是所有代码集中在一处:

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

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

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