2015-10-09 307 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