2016-07-14 34 views
1

我是在彈性搜索中對指標名稱建立索引。度量名稱的格式爲foo.bar.baz.aux。這是我使用的索引。術語聚合(實現分層刻面)查詢性能緩慢

{ 
    "index": { 
     "analysis": { 
      "analyzer": { 
       "prefix-test-analyzer": { 
        "filter": "dotted", 
        "tokenizer": "prefix-test-tokenizer", 
        "type": "custom" 
       } 
      }, 
      "filter": { 
       "dotted": { 
        "patterns": [ 
         "([^.]+)" 
        ], 
        "type": "pattern_capture" 
       } 
      }, 
      "tokenizer": { 
       "prefix-test-tokenizer": { 
        "delimiter": ".", 
        "type": "path_hierarchy" 
       } 
      } 
     } 
    } 
} 

{ 
    "metrics": { 
     "_routing": { 
      "required": true 
     }, 
     "properties": { 
      "tenantId": { 
       "type": "string", 
       "index": "not_analyzed" 
      }, 
      "unit": { 
       "type": "string", 
       "index": "not_analyzed" 
      }, 
      "metric_name": { 
       "index_analyzer": "prefix-test-analyzer", 
       "search_analyzer": "keyword", 
       "type": "string" 
      } 
     } 
    } 
} 

上述指標的度量標準名稱創建下列條款foo.bar.baz

foo 
bar 
baz 
foo.bar 
foo.bar.baz 

如果我有一堆指標,像下面

a.b.c.d.e 
a.b.c.d 
a.b.m.n 
x.y.z 

我要編寫一個查詢搶令牌的第n級。在上面的例子中

for level = 0, I should get [a, x] 
for level = 1, with 'a' as first token I should get [b] 
       with 'x' as first token I should get [y] 
for level = 2, with 'a.b' as first token I should get [c, m] 

我想不出任何其他方式,除了寫術語聚合。要找出a.b的二級令牌,下面是我提出的查詢。

time curl -XGET http://localhost:9200/metrics_alias/metrics/_search\?pretty\&routing\=12345 -d '{ 
     "size": 0, 
     "query": { 
     "term": { 
      "tenantId": "12345" 
     } 
     }, 
     "aggs": { 
      "metric_name_tokens": { 
       "terms": { 
        "field" : "metric_name", 
        "include": "a[.]b[.][^.]*", 
        "execution_hint": "map", 
        "size": 0 
       } 
      } 
     } 
    }' 

這會導致下面的問題。我解析輸出並從那裏抓取[c,m]。

"buckets" : [ { 
    "key" : "a.b.c", 
    "doc_count" : 2 
    }, { 
    "key" : "a.b.m", 
    "doc_count" : 1 
} ] 

到目前爲止好。該查詢適用於大多數租戶(請注意上面的tenantIdterm查詢)。對於有大量數據(大約1Million)的某些租戶來說,表現確實很慢。我猜測聚合的所有術語都需要時間。

我想知道術語聚合是否是這種數據的正確選擇,並且還在尋找其他可能的查詢類型。

+0

我不清楚你需要什麼。你需要計數嗎?或者你需要c和m嗎?或者您是否需要包含以下文件:a.b.c.d.e - a.b.c.d - a.b.m.n? –

+0

我只需要c和m。 – Chandra

+0

@JettroCoenradie我只需要c和m。基本上什麼是給定前綴的下一級可能令牌。 – Chandra

回答

1

幾點建議:

  • 「鏡子」的聚合過濾器在查詢部分水平以及。因此,對於a.b.匹配,請使用下列爲查詢並保持相同的AGGS部分:
"bool": { 
    "must": [ 
    { 
     "term": { 
     "tenantId": 123 
     } 
    }, 
    { 
     "prefix": { 
     "metric_name": { 
      "value": "a.b." 
     } 
     } 
    } 
    ] 
} 

甚至使用regexp具有相同的正則表達式作爲凝聚部。通過這種方式,聚合將不得不評估較少的桶,因爲到達聚合部分的文檔將更少。 你提到regexp對你來說效果更好,我最初的猜測是prefix會表現更好。

  • "size": 0從聚合變爲"size": 100。經過測試你提到這沒有任何區別
  • 刪除"execution_hint": "map"並讓Elasticsearch使用默認值。經過測試,你提到默認的execution_hint表現更差。
  • 我唯一能想到的其他事情就是通過在索引時移動它來減輕搜索時間的壓力。我的意思是:在索引時,在你自己的應用程序或者你正在使用的任何索引方法中,將文本分割爲程序化索引(而不是ES),並將索引中的每個元素索引到一個單獨的字段中。例如a.bfield2,a.b.cfield3等等。這對於同一個文件。然後,在搜索時間,根據搜索文本的內容查看特定字段。然而,這個想法在ES之外需要一些額外的工作。

從以上所有建議中,第一個建議的影響最大:查詢響應時間從23秒提高到了11秒。

+0

根據你對字符串abcde,abxy的建議,我會分別索引index [a],[ab],[abc],[abcd],[abcde],[abx],[abxy],然後如何搜索獲取跟隨前綴ab的所有令牌? – Chandra

+0

對於文檔,您應該具有以下結構:'{「tenantId」:123,「metric_name1」:[「a」,「x」],「metric_name2」:[「ab」,「xy」],「metric_name3」: [ 「ABC」, 「ABM」, 「XYZ」], 「metric_name4」:[ 「ABCD」, 「abmn」], 「metric_name5」:[ 「ABCDE」]}'。所有'metric_name *'字段將使用'關鍵字'分析器或任何不會分裂它的東西。查詢本身(因爲您希望允許用戶搜索'ab * .d'而不僅僅是'前綴'查詢)應該與''query_string「類似:{ 」default_field「:」metric_name *「, 」查詢「:」ab * .d「 }'。 –

+0

的聚合將是這樣的,雖然' 「AGGS」:{ 「metric_name_tokens」:{ 「術語」:{ 「場」: 「metric_name3」, 「大小」:0 } } }'。所以,基本上,對於'a.b。*。d'搜索,您只對'a.b.'後面的內容感興趣。你會使用'metric_name3'字段(具有三個層次結構的字段)。但我很想知道從query_string查詢中看到了什麼樣的性能。聚合部分會更輕。 –