對於ElasticSearch查詢,我們希望以不同的方式處理單詞(即令牌只包含字母)和非單詞。爲此,我們嘗試定義兩個分析器,要麼返回單詞,要麼返回非單詞。如何根據ElasticSearch中的正則表達式過濾令牌
例如,我們有一個描述產品的硬件存儲文檔:
{
"name": "Torx drive T9",
"category": "screws",
"size": 2.5,
}
然後用戶會搜索「梅花T9」,並期望找到這個文件。搜索T9會過於通用,並會提供太多不相關的產品。因此,如果我們已經找到'Torx',我們只想搜索'T9'術語。
我們努力創建這樣
{
"query": {
"bool": {
"must": {
"match: {
"name": {
"query": "Torx T9",
"analyzer": "words"
}
},
"should": {
"match: {
"name": {
"query": "Torx T9",
"analyzer": "nonwords"
}
}
}
}
}
的想法是,這將是簡單的創建令牌過濾器來做到這一點的查詢。例如:
"settings": {
"analysis": {
"filter": {
"words": {
"type": "pattern",
"pattern": "\\A\\p{L}*\\Z",
},
"nonwords": {
"type": "pattern",
"pattern": "\\P{L}",
}
}
}
但似乎沒有過濾器只匹配模式。相反,我們(AB)使用pattern_replace過濾器:
"settings": {
"analysis": {
"filter": {
"words": {
"type": "pattern_replace",
"pattern": "\\A((?=.*\\P{L}).*)",
"replacement": ""
},
"nonwords": {
"type": "pattern_replace",
"pattern": "\\A((?!.*\\P{L}).*)",
"replacement": ""
},
"nonempty": {
"type": "length",
"min":1
}
}
}
這與空的令牌,然後可以通過非空過濾除去取代不必要的令牌。這似乎工作,但所需的模式更晦澀。
有沒有更好的表達方式?
您是否還可以顯示一個或兩個示例文檔,並說明您想匹配的分別不匹配? – Val
也許另一個想法是使用[平板標記過濾器](https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-shingle-tokenfilter.html)來將單詞索引在一起,所以'T9'永遠不會被單獨索引,從而不能單獨搜索。仍然在尋找一種洗牌方式,這樣,您可以將它與索引牌過濾器一起編入索引:「torx驅動器」,「torx t9」,「驅動器t9」。我也在尋找[短語建議者](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-suggesters-phrase.html),這可能會提供一種方法來實現這一點。 – Val
我喜歡你提出的方法。如果過濾功能太笨重,只需將您的單詞和非單詞作爲索引器的一部分(ES外部)分隔到不同的字段中即可。 –