2015-10-21 57 views
0

我有一個Product模型,其中每個product有很多sku s。配置elasticsearch搜索和過濾有很多/屬於關係

我需要能夠通過兩種模型的elasticsearch進行搜索和過濾,但不太清楚如何去做。我目前上傳這種格式的elasticsearch:

[{ 
    id: 1 
    title: 'Product 1' 
    image: 'image1.jpg' 
    skus: [{ 
    id: 1 
    material: 'cotton' 
    quantity: 4 
    },{ 
    id: 2 
    material: 'polyester' 
    quantity: 22 
    }] 
},{ 
    ... 
}] 

我可以搜索標題就好了,但我不能確定,我怎麼會做這樣的事情

  • 搜索標題「foobar的」並按材料「棉花」和數量過濾> 5

這是可能與elasticsearch?

編輯

我願意接受不同的格式上傳或使用多個索引。

回答

1

我認爲parent/child relationship是你正在尋找。

作爲一個簡單的例子,我可以建立索引以這樣的父類型和子類型:

PUT /test_index 
{ 
    "mappings": { 
     "product": { 
     "properties": { 
      "id": { 
       "type": "long" 
      }, 
      "image": { 
       "type": "string" 
      }, 
      "title": { 
       "type": "string" 
      } 
     } 
     }, 
     "sku": { 
      "_parent": { 
      "type": "product" 
      }, 
     "properties": { 
      "id": { 
       "type": "long" 
      }, 
      "material": { 
       "type": "string" 
      }, 
      "quantity": { 
       "type": "long" 
      } 
     } 
     } 
    } 
} 

然後添加一個父文檔和兩個子文件:

POST /test_index/_bulk 
{"index":{"_type":"product","_id":1}} 
{"id": 1,"title": "Product1","image": "image1.jpg"} 
{"index":{"_type":"sku", "_id":1,"_parent":1}} 
{"id": 1,"material": "cotton","quantity": 4} 
{"index":{"_type":"sku","_id":2,"_parent":1}} 
{"id": 2,"material": "polyester","quantity": 22} 

現在如果我搜索"product""title": "Product1"有一個孩子"sku""material": "cotton""quantity"大於5,我不會找到一個:

POST /test_index/product/_search 
{ 
    "query": { 
     "filtered": { 
     "query": { 
      "match": { 
       "title": "Product1" 
      } 
     }, 
     "filter": { 
      "has_child": { 
       "type": "sku", 
       "filter": { 
        "bool": { 
        "must": [ 
         { 
          "term": { 
           "material": "cotton" 
          } 
         }, 
         { 
          "range": { 
           "quantity": { 
           "gt": 5 
           } 
          } 
         } 
        ] 
        } 
       } 
      } 
     } 
     } 
    } 
} 
... 
{ 
    "took": 2, 
    "timed_out": false, 
    "_shards": { 
     "total": 1, 
     "successful": 1, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 0, 
     "max_score": null, 
     "hits": [] 
    } 
} 

但是如果我搜索了"product""title": "Product1",有一個孩子"sku""material": "polyester""quantity"大於5,我找到一個:

POST /test_index/product/_search 
{ 
    "query": { 
     "filtered": { 
     "query": { 
      "match": { 
       "title": "Product1" 
      } 
     }, 
     "filter": { 
      "has_child": { 
       "type": "sku", 
       "filter": { 
        "bool": { 
        "must": [ 
         { 
          "term": { 
           "material": "polyester" 
          } 
         }, 
         { 
          "range": { 
           "quantity": { 
           "gt": 5 
           } 
          } 
         } 
        ] 
        } 
       } 
      } 
     } 
     } 
    } 
} 
... 
{ 
    "took": 2, 
    "timed_out": false, 
    "_shards": { 
     "total": 1, 
     "successful": 1, 
     "failed": 0 
    }, 
    "hits": { 
     "total": 1, 
     "max_score": 1.4054651, 
     "hits": [ 
     { 
      "_index": "test_index", 
      "_type": "product", 
      "_id": "1", 
      "_score": 1.4054651, 
      "_source": { 
       "id": 1, 
       "title": "Product1", 
       "image": "image1.jpg" 
      } 
     } 
     ] 
    } 
} 

下面是一些代碼我用來測試:

http://sense.qbox.io/gist/d1989a28372ac9daae335d585601c11818b2fa11

+0

這很好。有沒有什麼辦法讓孩子們的產品與產品一起迴歸? – tyler

+1

我想你必須要做第二次請求。 ['has_parent'](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-has-parent-query.html)在那裏可能很有用。 –