2016-06-07 177 views
1

我有兩個指標 - 一個包含_id=<url of the document>,例如「文檔」對象http://site/folder/document_name.doc;另一個包含與_id=<url of the folder>,例如「文件夾中的」對象http://site/folder匹配的部分網址

在我的node.js腳本我需要匹配的文檔文件夾,即我搜索所有文件夾中的網址,然後爲他們每個人我尋找其網址的開頭的文件夾網址

我的所有文件似乎無法構建正確的查詢,將返回所有文檔_id開始http://site/folder

任何想法?

回答

2

我認爲更好的解決辦法是不使用_id這個問題。

取而代之的是,索引字段名爲path(或任何您想要的名稱),並使用Path Hierarchy Tokenizer以及一些創意令牌過濾器來查看。

這樣,您就可以使用Elasticsearch/Lucene的來標記網址。

例如:https://site/folder被符號化視爲兩個標記:

  • site
  • site/folder

然後,您可以通過搜索權包含在site文件夾中的任何文件或文件夾令牌:site

PUT /test 
{ 
    "settings": { 
    "analysis": { 
     "filter": { 
     "http_dropper": { 
      "type": "pattern_replace", 
      "pattern": "^https?:/{0,}(.*)", 
      "replacement": "$1" 
     }, 
     "empty_dropper": { 
      "type": "length", 
      "min": 1 
     }, 
     "qs_dropper": { 
      "type": "pattern_replace", 
      "pattern": "(.*)[?].*", 
      "replacement": "$1" 
     }, 
     "trailing_slash_dropper": { 
      "type": "pattern_replace", 
      "pattern": "(.*)/+$", 
      "replacement": "$1" 
     } 
     }, 
     "analyzer": { 
     "url": { 
      "tokenizer": "path_hierarchy", 
      "filter": [ 
      "http_dropper", 
      "qs_dropper", 
      "trailing_slash_dropper", 
      "empty_dropper", 
      "unique" 
      ] 
     } 
     } 
    } 
    }, 
    "mappings": { 
    "type" : { 
     "properties": { 
     "url" : { 
      "type": "string", 
      "analyzer": "url" 
     }, 
     "type" : { 
      "type": "string", 
      "index": "not_analyzed" 
     } 
     } 
    } 
    } 
} 

您可以可能不希望我加入trailing_slash_dropper。將lowercase令牌過濾器放在那裏也是值得的,但實際上可能會使某些URL令牌根本上不正確(例如,mysite.com/bucket/AaDsaAe31AcxX可能真的關心這些字符的情況)。你可以把分析儀與_analyze端點試駕:

GET /test/_analyze?analyzer=url&text=http://test.com/text/a/?value=xyz&abc=value 

注:我使用感,所以它的URL編碼對我來說。這將產生三個令牌:

{ 
    "tokens": [ 
    { 
     "token": "test.com", 
     "start_offset": 0, 
     "end_offset": 15, 
     "type": "word", 
     "position": 0 
    }, 
    { 
     "token": "test.com/text", 
     "start_offset": 0, 
     "end_offset": 20, 
     "type": "word", 
     "position": 0 
    }, 
    { 
     "token": "test.com/text/a", 
     "start_offset": 0, 
     "end_offset": 22, 
     "type": "word", 
     "position": 0 
    } 
    ] 
} 

綁一起:

POST /test/type 
{ 
    "type" : "dir", 
    "url" : "https://site" 
} 

POST /test/type 
{ 
    "type" : "dir", 
    "url" : "https://site/folder" 
} 

POST /test/type 
{ 
    "type" : "file", 
    "url" : "http://site/folder/document_name.doc" 
} 

POST /test/type 
{ 
    "type" : "file", 
    "url" : "http://other/site/folder/document_name.doc" 
} 

POST /test/type 
{ 
    "type" : "file", 
    "url" : "http://other_site/folder/document_name.doc" 
} 

POST /test/type 
{ 
    "type" : "file", 
    "url" : "http://site/mirror/document_name.doc" 
} 

GET /test/_search 
{ 
    "query": { 
    "bool": { 
     "must": [ 
     { 
      "match": { 
      "url": "http://site/folder" 
      } 
     } 
     ], 
     "filter": [ 
     { 
      "term": { 
      "type": "file" 
      } 
     } 
     ] 
    } 
    } 
} 

它來測試這一點,以便你可以看到什麼比賽是非常重要的,和那些比賽的順序。當然,這會找到您期望找到的文檔(並將其放在最上面!),但它也會找到其他一些您可能不期待的文檔,如http://site/mirror/document_name.doc,因爲它共享基本標記:site。有一堆,你可以用它來排除這些文件如果它排除他們是非常重要的策略。

你可以利用你的標記化執行類似谷歌的結果過濾,喜歡怎樣就可以通過谷歌搜索特定的域:

匹配查詢網站:elastic.co

你可以然後解析(手動地)的site:elastic.co並採取elastic.co爲邊界URL:

{ 
    "term" : { 
    "url" : "elastic.co" 
    } 
} 

否這與搜索URL不同。你明確地說「只包含這個確切的令牌在他們的url中的文檔」。您可以繼續使用site:elastic.co/blog等,因爲該確切標記存在。但是,需要注意的是,如果您要嘗試site:elastic.co/blog/,那麼將不會找到任何文檔,因爲該令牌在給定令牌過濾器時不能存在。

+0

很好的答案,謝謝 - 我用它成功了! – Andrey