2014-01-20 50 views
5

我基於ElasticSearch對電子商務產品目錄進行原型設計。 每個產品都被編入索引文件(其中包含名稱和說明等屬性)。ElasticSearch基於不同類型的查詢提高文檔評分

有一件事我不能解決,我想根據用戶的購買記錄提高某些產品的分數。

我能想到的唯一選擇是將購買歷史記錄存儲爲產品的子文檔。然後使用帶過濾器的custom_filters_score,查找具有給定userId的子文檔。在這種情況下,過濾器確定給定用戶是否已經購買了給定產品,如果是,則會提高分數。

此方法的問題在於某些產品可能每個月都會購買數十萬次,而且我不確定ElasticSearch在這種情況下的性能如何。

完美的解決方案是,如果我可以將購買歷史放在單獨的索引或相同的索引中,但是作爲不同的文檔類型(比如說'userspurchasehistory')。示例文檔:

{userId: 1234, purchesedProducts: [34,112323,1223,32342,31234]} 

然後使用查詢得分升壓表達是這樣的:如果術語34(的productId)存在於userspurchasehistory(類型)的文件的「purchesedProducts」(字段名稱),其具有「用戶id」等於1234,然後按因子2提升查詢。

此處有任何想法或想法?

UPDATE:

我已經進行了一些測試的產品大目錄和銷售數據的一個很大的量: 產品(類型)的文件數:500 000 SalesHistory的(類型)的文件數: 14 000 000 索引尺寸:2.5GB 彈性波紋:一個節點,所有默認設置

SalesHistory docuemtns是產品文檔的子文檔。 鋪貨銷售的條目:

~20% of products: 40 entries 
~20% of products: 30 entries 
~20% of products: 20 entries 
~20% of products: 10 entries 
~20% of products: 5 entries 

200 products with 10 000 sales entries (plus previously added 5-40 entries) 
200 products with 5 000 sales entries (plus previously added 5-40 entries) 
200 products with 2 500 sales entries (plus previously added 5-40 entries) 
200 products with 1 000 sales entries (plus previously added 5-40 entries) 
200 products with 500 sales entries (plus previously added 5-40 entries) 
1 product 18 500 entries 

例子查詢:

curl -XGET "http://localhost:9200/demoproducts/_search" -d' 
{ 
    "query": { 
     "custom_filters_score": { 
     "query": { 
      "match_all": {} 
     } 
     }, 
     "filters": [ 
     { 
      "filter": { 
       "has_child": { 
        "type": "saleshistory", 
        "query": { 
        "term": { 
         "userId": { 
          "value": "28875" 
         } 
        } 
        } 
       } 
      }, 
      "boost": 2 
     } 
     ] 
    } 
}' 

結果:

{ 
    "took": 33, 
    "timed_out": false, 
    "_shards": { 
    "total": 5, 
    "successful": 5, 
    "failed": 0 
    }, 
    "hits": { 
    "total": 500001, 
    "max_score": 2 
    ... 
    } 
} 

當我加入了一些過濾器,以我的查詢(幾乎在所有情況下,我們查詢包含一些過濾器)響應時間大約是7ms

結論

沒有必要以任何其他方式實施這種情況下,然後作爲子文件。

回答

1

而不是修改文檔,您可以動態地建立一個條款查詢與用戶的購買歷史記錄。

curl -XGET "http://localhost:9200/demoproducts/_search" -d' 
    { 
     "query": { 
      "terms": {"id":["34","112323","1223","32342","31234"]} 
     } 
    } 
}