細心的開發者如果已經閱讀我前兩天發布的文章 “Elastic 8.17:Elasticsearch logsdb 索引模式、Elastic Rerank 等”,你就會發現在 8.17 的發布版中,有一個重要的功能發布。那就是 ES|QL 開始支持全文搜索了。在今天的文章中我們來嘗試一下。
ES|QL 中新的 MATCH 和查詢字符串 (QSTR) 函數的技術預覽使日志搜索更加輕松直觀。MATCH 使用 Lucene 匹配查詢在 ES|QL 中提供全文搜索功能,而 QTSR 通過啟用 Lucene 查詢字符串查詢來幫助更高級地過濾日志數據。
ES|QL 的全文搜索使 Discover 中的搜索更加輕松、性能更高,尤其是在處理多個術語或條件邏輯時。
ES|QL 中的這些新搜索功能提供了顯著的性能改進。查詢現在可以比等效 RLIKE 查詢快 50 倍到 1000 倍,尤其是在較大的數據集上。將此功能添加到 ES|QL 允許你利用 Elastic 的主要優勢之一 - 能夠提前索引所有數據 - 從而一次性完成繁重的工作并在以后實現真正快速的全文搜索。
所有這些都與 Elasticsearch DSL 函數緊密結合,以便在搜索中實現更好的功能奇偶校驗、直觀性和速度。 ES|QL 還提供完整的地理搜索功能,并顯著改善按距離排序的延遲。
MATCH function
警告:請勿在生產環境中使用。此功能處于技術預覽階段,可能會在未來版本中更改或刪除。Elastic 將努力修復任何問題,但技術預覽中的功能不受官方 GA 功能的支持 SLA 約束。
語法:
參數:
參數 | 描述 |
---|---|
field | 查詢將針對的字段。 |
query | 你希望在提供的字段中查找的文本。 |
支持的類型:
field | query | result |
---|---|---|
keyword | keyword | boolean |
keyword | text | boolean |
text | keyword | boolean |
text | text | boolean |
示例:
我們首先來創建如下的一個 books 索引:
PUT books
{"mappings": {"properties": {"title": {"type": "keyword"},"author": {"type": "text"},"book_no": {"type": "long"}}}
}
如上所示,我們創建了3個字段,它們分別有不同的屬性。我們使用如下的命令來寫入文檔:
PUT books/_bulk
{"index": {"_id": "1"}}
{"title":"Whispers of Eternity", "book_no": 2378, "author": "[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]"}
{"index": {"_id": "2"}}
{"title":"The Crimson Horizon", "book_no": 2713, "author": "William Faulkner"}
{"index": {"_id": "3"}}
{"title":"Shadows in Bloom", "book_no": 2847, "author": "Colleen Faulkner"}
{"index": {"_id": "4"}}
{"title":"Echoes of Tomorrow", "book_no": 2883, "author": "William Faulkner"}
{"index": {"_id": "5"}}
{"title":"Beneath the Ashen Sky", "book_no": 2713, "author": "Danny Faulkner"}
我們進行如下的搜索:
POST _query?format=txt
{"query": """FROM books| WHERE MATCH(author, "Faulkner")| KEEP book_no, author| SORT book_no| LIMIT 5"""
}
上面的命令得到的結果是:
book_no | author
---------------+--------------------------------------------------
2378 |[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
2713 |Danny Faulkner
2713 |William Faulkner
2847 |Colleen Faulkner
2883 |William Faulkner
如果我們去掉那個 SORT,我們可以看到的排序結果是:
POST _query?format=txt
{"query": """FROM books| WHERE MATCH(author, "Faulkner")| KEEP book_no, author| LIMIT 5"""
}
我們得到的結果是:
book_no | author
---------------+--------------------------------------------------
2378 |[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
2713 |William Faulkner
2847 |Colleen Faulkner
2883 |William Faulkner
2713 |Danny Faulkner
我們把搜索詞的大小寫改一下成 “faulKner",我們看看能否得到我們想要的結果:
POST _query?format=txt
{"query": """FROM books| WHERE MATCH(author, "faulKner")| KEEP book_no, author| LIMIT 5"""
}
我們得到的結果是:
book_no | author
---------------+--------------------------------------------------
2378 |[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
2713 |William Faulkner
2847 |Colleen Faulkner
2883 |William Faulkner
2713 |Danny Faulkner
很顯然,我們得到的是同樣的結果,盡管我們把搜索詞的大小寫都改變了。
我們再次做如下的搜索:
POST _query?format=txt
{"query": """FROM books| WHERE MATCH(author, "Danny")| KEEP book_no, author| LIMIT 5"""
}
我們得到的結果是:
book_no | author
---------------+---------------
2713 |Danny Faulkner
很顯然這次只有一個結果。但是如果我們這樣來進行搜索:
POST _query?format=txt
{"query": """FROM books| WHERE MATCH(author, "Danny Faulkner")| KEEP book_no, author| LIMIT 5"""
}
我們得到的結果是:
book_no | author
---------------+--------------------------------------------------
2378 |[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
2713 |William Faulkner
2847 |Colleen Faulkner
2883 |William Faulkner
2713 |Danny Faulkner
這次得到的結果有點出乎我們的意料。我們更希望 “Danny Faulkner” 成為排名第一的結果。很顯然這個結果并不是我們想要的。
我們接下來針對 keyword 字段來進行測試:
POST _query?format=txt
{"query": """FROM books| WHERE MATCH(title, "The Crimson Horizon")| KEEP book_no, title| LIMIT 5"""
}
我們得到的結果是:
book_no | title
---------------+---------------------
2713 |The Crimson Horizon
2713 |Beneath the Ashen Sky
很顯然,第二個結果中有一個 the 匹配,所以在召回里含有這個書目。這個還是全文搜索,盡管 title 字段是 keyword。
如果我們把 The 改成 the, 我們得到的是一樣的結果:
POST _query?format=txt
{"query": """FROM books| WHERE MATCH(title, "the Crimson Horizon")| KEEP book_no, title| LIMIT 5"""
}
我們可以和以前不使用 MATCH function 的查詢來進行比較:
POST _query?format=txt
{"query": """FROM books| WHERE author LIKE "William *"| KEEP book_no, author| LIMIT 5"""
}
上面返回結果:
book_no | author
---------------+----------------
2713 |William Faulkner
2883 |William Faulkner
這是一種 keyword 的搜索 盡管 author 字段是 text 字段。如果我們進行如下的搜索:
POST _query?format=txt
{"query": """FROM books| WHERE author LIKE "william *"| KEEP book_no, author| LIMIT 5"""
}
上面的搜索將沒有任何的結果。
QSTR function
警告:請勿在生產環境中使用 VALUES。此功能處于技術預覽階段,可能會在未來版本中更改或刪除。Elastic 將努力修復任何問題,但技術預覽中的功能不受官方 GA 功能的支持 SLA 約束。
語法:
參數:
參數 | 描述 |
---|---|
query | Lucene 查詢字符串格式的查詢字符串。 |
描述:
執行查詢字符串查詢。如果提供的查詢字符串與行匹配,則返回 true。
query | result |
---|---|
keyword | boolean |
text | boolean |
示例:
我們使用如下的示例來進行展示:
POST _query?format=txt
{"query": """FROM books| WHERE QSTR("author: Faulkner")| KEEP book_no, author| LIMIT 5"""
}
上面命令返回的結果是:
book_no | author
---------------+--------------------------------------------------
2378 |[Carol Faulkner, Holly Byers Ochoa, Lucretia Mott]
2713 |William Faulkner
2847 |Colleen Faulkner
2883 |William Faulkner
2713 |Danny Faulkner