Re: [問題] QT Sqlite語法以及全文檢索FTS問題

作者: pinefruit (莫使惹塵埃)   2021-11-19 20:44:12
※ 引述《liu2007 (薯)》之銘言:
: 我的開發平台是 win7
: 工具是QT Creator
: 版本是Qt Core 5.15.2
: 在寫一些存取Sqlite資料庫的程式碰到了兩個問題。
: 1.當要查詢的字當中包含sql語法保留字的時候:
: QString keyword;
: QString queryString{"SELECT * FROM exfts WHERE nameEN match ?"};
: query.prepare(queryString);
: query.addBindValue(keyword);
: 當keyword是sql語法的保留字,例如:AND, OR等等,querry會失敗
: 想請問QT有相對應函式可以解決嗎?
: 還是只能自己判斷如果要搜的關鍵字是保留字的時候
: querryString要自己變成
: QString queryString{"SELECT * FROM exfts WHERE nameEN match " +
: "'"+ keyword +"';"};
還是可以繼續用 addBindValue(),只要幫該關鍵字加上引號即可。
例如:addBindValue("'OR'") 或 addBindValue("\"OR\"")
: 2.第二個問題就是在使用全文檢索FTS的時候
: match + 萬用字元* 跟
: 一般普通的sql語法 like + 萬用字元%
: 兩者似乎有什麼不一樣
: 如果我想要找有包含「水果」兩個字的欄位
: 使用 like '%水果%'搜尋
: 那不管是
: 1.好吃的水果
: 2.好吃 水果真的很好吃
: 3.好吃 水果 真的很好吃
: 3.好吃-水果-真的很好吃
: 都可以撈出來
: 但如果是match '水果'
: 只有3會被撈出來
: 如果使用match '*水果*'
: 有時候可以被撈出來
: 也有可能不會被撈出來
: 因為這是之前碰到的問題現在才來問
: 所以當時的資料庫資料以及下的關鍵字我一時舉例不上來
: 我下班之後如果有找到例子會再補上
: 目前只確定使用match '關鍵字'的時候
: 兩旁有用空白切開來的欄位才會被撈出來,例如上述的3
: 其他包含在一句沒斷開的句子裡則不會撈出來
: 用萬用字元擺前或擺後也沒有正確撈出
: 想請問是我完全搞錯FTS的萬用字元*的用法
: 還是是因為非英語的文字分割字詞的關係?
: 又或是其他原因呢?
: 感謝閱讀
先簡單回答,
MATCH 做的是 token query,而 LIKE 做的則是 pattern matching。
詳細一點解釋的話,
MATCH 比較的是字串中的 token,
而只有前後是空白或特殊字元的部分才會被歸類成 token。
例如在以下三個例子中,term 都會是 token:
"a short term", "long-term", "a_legal_term"
但如果是 "terminology" 的話,term 就不是一個 token 了,
因此用 MATCH 'term' 是找不到它的。
另外,使用萬用字元 * 的 MATCH,稱為 token prefix query,
它一樣只會拿來和 token 做比較,且只會比較該 token 的前綴部分(prefix)。
例如使用 MATCH 'ter*' 的話,上面四個例子都會被找到,
但如果使用 MATCH '*erm' 則不會有任何匹配。
至於 LIKE 比較的則是整個字串,而非其中的 token,
也就是說,整個字串都必須符合 LIKE 後面寫的 pattern,才算滿足條件。
兩者的差異大概是這樣子,有錯誤的地方再煩請指正。
作者: liu2007 (è–¯)   2021-11-19 21:58:00
我在上班有偷偷查資料,關於萬用字元*的部分也是查到說只能match開頭的資料,從另外一個角度來說,像fts這種建索引的方式的資料庫,要它去找match結尾等於是要把整個資料翻一遍,就違背建索引的目的了XD至於第一個問題我query用問號然後再去addbindvalue的原因就是我的資料除了有可能AND等保留字以外,還會有'和"這種這種符號,如果bind上去之前都要檢查是否包含'或"免得query下錯,看起來有點多此一舉又莫可奈何,所以才會想用問號的方式,但沒想到現在?沒辦法解決保留字的問題...感謝回答

Links booklink

Contact Us: admin [ a t ] ucptt.com