2012-08-24 108 views
16

假設在我的elasticsearch索引中,我有一個名爲「dots」的字段,其中包含一串標點符號分隔的詞語(例如「first.second.third」)。如何匹配Elasticsearch中的前綴

我需要搜索例如「first.second」,然後獲取其「dots」字段包含的字符串完全是「first.second」或以「first.second。」開頭的所有條目。

我有一個問題,理解文本查詢的工作方式,至少我沒有能夠創建一個查詢來完成這項工作。在

$ curl -XGET http://localhost:9200/myapp/index -d '{ 
    "dots": "first.second*" 
}' 

更多的例子有關語法:

回答

20

Elasticsearch有Path Hierarchy Tokenizer,它是爲這種用例準確創建的。下面是如何將其設置爲索引的例子:

# Create a new index with custom path_hierarchy analyzer 
# See http://www.elasticsearch.org/guide/reference/index-modules/analysis/pathhierarchy-tokenizer.html 
curl -XPUT "localhost:9200/prefix-test" -d '{ 
    "settings": { 
     "analysis": { 
      "analyzer": { 
       "prefix-test-analyzer": { 
        "type": "custom", 
        "tokenizer": "prefix-test-tokenizer" 
       } 
      }, 
      "tokenizer": { 
       "prefix-test-tokenizer": { 
        "type": "path_hierarchy", 
        "delimiter": "." 
       } 
      } 
     } 
    }, 
    "mappings": { 
     "doc": { 
      "properties": { 
       "dots": { 
        "type": "string", 
        "analyzer": "prefix-test-analyzer", 
        //"index_analyzer": "prefix-test-analyzer", //deprecated 
        "search_analyzer": "keyword" 
       } 
      } 
     } 
    } 
}' 
echo 
# Put some test data 
curl -XPUT "localhost:9200/prefix-test/doc/1" -d '{"dots": "first.second.third"}' 
curl -XPUT "localhost:9200/prefix-test/doc/2" -d '{"dots": "first.second.foo-bar"}' 
curl -XPUT "localhost:9200/prefix-test/doc/3" -d '{"dots": "first.baz.something"}' 
curl -XPOST "localhost:9200/prefix-test/_refresh" 
echo 
# Test searches. 
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true" -d '{ 
    "query": { 
     "term": { 
      "dots": "first" 
     } 
    } 
}' 
echo 
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true" -d '{ 
    "query": { 
     "term": { 
      "dots": "first.second" 
     } 
    } 
}' 
echo 
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true" -d '{ 
    "query": { 
     "term": { 
      "dots": "first.second.foo-bar" 
     } 
    } 
}' 
echo 
curl -XPOST "localhost:9200/prefix-test/doc/_search?pretty=true&q=dots:first.second" 
echo 
+0

對不起,直到現在沒有看到你的帖子!非常感謝:)我會盡快查看它! – Stine

+0

如何在我的Java代碼中執行設置和映射? – Stine

+1

'client.admin()。indices()。prepareCreate(「test」)。addMapping(「type1」,mapping).setSettings(settings).execute().actionGet();' – imotov

2

看一看prefix queries

$ curl -XGET 'http://localhost:9200/index/type/_search' -d '{ 
    "query" : { 
     "prefix" : { "dots" : "first.second" } 
    } 
}' 
+1

當字符串包含標點時不起作用:/ – Stine

+1

[This](https://gist.github.com/3457388)適用於新索引。你的索引有特殊的映射嗎?也許你應該嘗試一個新的,乾淨的索引。 – A21z

+0

使用前綴搜索或路徑分級標記化器有沒有效率差異? –

1

還有一個更簡單的方法,如elasticsearch documentation指出:

只需使用:

{ 
    "text_phrase_prefix" : { 
     "fieldname" : "yourprefix" 
    } 
} 

或因爲0.19.9:

{ 
    "match_phrase_prefix" : { 
     "fieldname" : "yourprefix" 
    } 
} 

代替:

{ 
    "prefix" : { 
     "fieldname" : "yourprefix" 
} 
1

我正在尋找一個類似的解決方案 - 但只匹配一個前綴。我發現@ imtov的answer讓我幾乎沒有,但對於一個變化 - 各地切換分析:的

"mappings": { 
    "doc": { 
     "properties": { 
      "dots": { 
       "type": "string", 
       "analyzer": "keyword", 
       "search_analyzer": "prefix-test-analyzer" 
      } 
     } 
    } 
} 

代替

"mappings": { 
    "doc": { 
     "properties": { 
      "dots": { 
       "type": "string", 
       "index_analyzer": "prefix-test-analyzer", 
       "search_analyzer": "keyword" 
      } 
     } 
    } 
} 

這樣補充道:

'{"dots": "first.second"}' 
'{"dots": "first.third"}' 

將增加只有這些完整的令牌,不需要存儲first,second,third令牌。

然而,尋找任何

first.second.anyotherstring 
first.second 

將正確只返回第一個條目:

'{"dots": "first.second"}' 

你問不正是對,但不知何故相關的,所以我想能幫助別人。