MySQL toàn văn đối xử từ e-magazine
trong một văn bản như một cụm từ và không như một từ. Do đó, kết quả là hai từ e
và magazine
. Và trong khi nó xây dựng chỉ mục tìm kiếm, nó không thêm e
vào chỉ mục vì ft_min_word_len
(mặc định là 4 ký tự).
Giới hạn độ dài tương tự được sử dụng cho truy vấn tìm kiếm. Đó là lý do tại sao tìm kiếm e-magazine
trả lại kết quả giống hệt như a-magazine
vì a
và -
bị bỏ qua hoàn toàn.
Nhưng bây giờ bạn muốn tìm cụm từ chính xác e-magazine
.Bằng cách đó bạn sử dụng dấu ngoặc kép và đó là cách hoàn chỉnh đúng để tìm các cụm từ, nhưng MySQL không hỗ trợ các nhà khai thác cho các cụm từ, chỉ cho chữ:
https://dev.mysql.com/doc/refman/5.7/en/fulltext-boolean.html
Với sửa đổi lần này, nhân vật nào đó có ý nghĩa đặc biệt tại bắt đầu hoặc kết thúc của lời trong chuỗi tìm kiếm
Một số người sẽ đề nghị sử dụng các truy vấn sau đây:
SELECT id, name
FROM company
WHERE MATCH(name) AGAINST('e-magazi*' IN BOOLEAN MODE)
HAVING name LIKE 'e-magazi%';
Như tôi đã nói, MySQL bỏ qua số e-
và tìm kiếm từ ký tự đại diện magazi*
. Sau khi các kết quả đó được giải thích, nó sử dụng HAVING
để lọc kết quả theo cách thủ công cho e-magazi*
bao gồm e-
. Bằng cách đó bạn sẽ tìm thấy cụm từ e-magazine AG
. Tất nhiên HAVING
chỉ cần thiết nếu cụm từ tìm kiếm chứa toán tử ký tự đại diện và bạn không bao giờ nên sử dụng dấu ngoặc kép. Toán tử này được sử dụng bởi người dùng của bạn chứ không phải bạn!
Lưu ý: Khi bạn không bao quanh cụm từ tìm kiếm với %
, nó sẽ chỉ tìm các trường bắt đầu bằng từ đó. Và bạn không muốn bao quanh nó, bởi vì nó cũng sẽ tìm thấy bee-magazine
. Vì vậy, có thể bạn cần thêm OR HAVING name LIKE ' %e-magazi%' OR HAVING NAME LIKE '\\n%e-magazi%'
để làm cho nó có thể sử dụng được bên trong văn bản.
Lừa
Nhưng cuối cùng tôi thích một thủ thuật để HAVING
là không cần thiết ở tất cả:
- Nếu bạn thêm văn bản với bảng cơ sở dữ liệu của bạn, thêm họ thêm vào một cột toàn văn riêng biệt được lập chỉ mục và thay thế các từ như
up-to-date
bằng up-to-date uptodate
.
- Nếu người dùng tìm kiếm
up-to-date
thay thế nó trong truy vấn bằng uptodate
.
Bằng cách đó bạn vẫn có thể tìm thấy specific
trong user-specific
nhưng up-to-date
cũng (và không chỉ date
).
Bonus
Nếu người dùng tìm kiếm -well-known huge ports
MySQL coi đó như là not include *well*, could include *known* and *huge*
. Tất nhiên bạn cũng có thể giải quyết điều đó bằng một biến thể truy vấn khác, nhưng với mẹo ở trên, bạn xóa dấu gạch ngang để truy vấn tìm kiếm trông giống như vậy:
SELECT id
FROM texts
WHERE MATCH(text) AGAINST('-wellknown huge ports' IN BOOLEAN MODE)
Câu hỏi thú vị. Tôi có thể sao chép nó ở đây trong một bảng với một trường uuid như. 'SELECT id, bootid FROM socket WHERE MATCH (bootid) AGAINST ('+" 18bda775 "' IN BOOLEAN MODE);' sẽ hoạt động và nếu tôi tìm kiếm "18bda775-711c", nhưng tìm kiếm "18bda" hoặc "18bda775 -711 "sẽ không hoạt động. trường 'bootid' trong câu hỏi chứa: 18bda775-711c-4329-9de2-a3d81dc13d06 –
Chúng tôi cũng đã thử thay đổi các ký tự điều khiển boolean để sử dụng # thay vì - nhưng nó không có hiệu lực (có, tôi đã sửa chỉ mục bảng sau khi thay đổi) : 'ft_boolean_syntax = + #><() ~ *:" "& |' – hajo