配置elasticsearch以进行搜索和过滤具有多个/属于关系

时间:2015-10-21 18:52:51

标签: elasticsearch

我有一个Product模型,其中每个product都有很多sku个。

我需要能够在两个模型中通过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

弹性搜索有可能吗?

修改

我愿意以不同的格式上传或使用多个索引。

1 个答案:

答案 0 :(得分:1)

我认为parent/child relationship正是您正在寻找的。

作为一个简单的例子,我可以设置一个父类型和子类型的索引,如下所示:

function house_num($id,$name){
switch($id){
 //call functions...
}

然后添加父文档和两个子文档:

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"的{​​{1}},其子"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