2015-10-09 182 views
1

具有像这样的多级嵌套字段的映射:Elasticsearch多级嵌套查询

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

查询没有找到,即使省内场缺少给定的记录,相反,它正常工作,如果我们用“威尼托”为大区和“特雷维索”为省报。 Nome并且在其他嵌套对象中使用comune字段。

为什么此查询不工作?

回答

0

试图改变你的条件为小写。既然你不要在您映射指定一个分析仪,standard analyzer使用,这将转化方面小写。

您的查询是相当介入,起初我还以为你可能需要更多"nested"条款,但是当我做了以下内容,它似乎工作。 (我没有经历这个很快,所以让我知道,如果我在这里表示不为你工作,出于某种原因。)

我不得不拿出"query"的部分,因为我在"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

+0

感谢重播,示例查询做工精细。尽管如此,还是有一些更复杂的数据的结果,使我认为我没有很好地获得嵌套的东西。在对象特雷维索与大区: – bn89

+0

例如,如果我们增加一个COMUNI场(诺姆:Treviso2)附近诺姆威尼托和使用作为查询参数威尼托,威尼斯和XXX没有找到对象,即使在省COMUNI场=威尼斯同时采用treviso2代替XXX返回的记录,即使treviso2是不是在威尼斯,但特雷维索是空的。也许查询正在寻找父领域?我想获得的是,如果上层匹配所有嵌套层次必须匹配上层匹配对象。 – bn89