2013-07-03 15 views
7

DB üzerinde tam metin araması yapan bir arama sorgum var. Ben 'Cardozo, Horacio' veya 'Cardozo' veya 'horacio' aradığınız zamanMySQL tam metin arama birden çok sütun üzerinde: sonuç karışıklığı

$sql = "SELECT 
* 
FROM 
`tbl_auction_listing` AS `al` 
JOIN 
`tbl_user` AS `u` ON `al`.`user_id` = `u`.`user_id` 
LEFT JOIN 
`tbl_gallery_details` AS `gd` ON `al`.`user_id` = `gd`.`user_id` 
LEFT JOIN 
`tbl_self_represented_details` AS `sr` ON `u`.`user_id` = `sr`.`user_id` 
WHERE 
`al`.`status` = '" . ACTIVE . "' 
AND 
`al`.`start_date` < NOW() 
AND 
`al`.`end_date` > NOW() 
AND 
MATCH(`al`.`listing_title`, 
`al`.`description`, 
`al`.`provenance`, 
`al`.`title`, 
`al`.`artist_full_name`, 
`al`.`artist_first_name`, 
`al`.`artist_last_name`, 
`sr`.`artist_name`, 
`gd`.`gallery_name`, 
`u`.`username`) AGAINST('$search_query' IN BOOLEAN MODE)"; 

Ben hiçbir sonuç ancak artist_full_name = Cardozo, Horacio ile db 2 kayıtlarla bir sanatçı olduğunu biliyorum olsun.

Bütün MAÇ alanlarını kaldırmak ve sadece al varsa

. artist_full_name 2 sonuç alacağım. al'da eklerseniz. description 1 sonuç aldım çünkü 'Horacio Cardozo' açıklamasında var.

herhangi koşul (herhangi bir arama sorgusu kelime) MAÇ alanların herhangi birinde bir araya geldi eğer arama tüm kayıtları döndürmek için bir yol var mı? IN BOOLEAN MODU'nu kaldırmayı denedim ama aynı sonuçları üretti.

+0

yerine 'BOOLE MODE' İÇİNDE, DOĞAL DİL MODE' –

+0

İÇİNDE' denemek 'DOĞAL DİL MODE' varsayılan moddur İÇİNDE – RandomSeed

+0

Hala 0 sonuçlar üretir.DB'deki tüm alanların tam metin olduğunu ve hala hiçbir şey olmadığını kontrol ettim. – puks1978

cevap

15

O InnoDB tablolar aynı MATCH() durumda birkaç tam metin dizinleri üzerinde arama izin vermez anlaşılmaktadır.

İşte alanların hepsi bu yüzden farklı endeksler kapsamındadır, aynı tabloya ait değil. ,

CREATE TABLE t (
    f1 VARCHAR(20), 
    f2 VARCHAR(20), 
    FULLTEXT(f1), FULLTEXT(f2) 
) ENGINE=InnoDB; 

SELECT * FROM t 
WHERE MATCH(f1, f2) AGAINST ('something in f2'); -- likely to return no row 

bir tam arama sadece karşılaştığında ilk tam dizin aratabilecekleri gibi It görünüyor ama bu from this experience düşeriz sadece bir şeydir edin: Eğer böyle bir tablo olsaydı aynı sınırlama geçerlidir edin bunu kabul edilmez. Bu auction ve birinde iki ayrı dizin olsaydı olası bir sorgunun bir tasviridir

SELECT * FROM auction, user, gallery, ... 
WHERE 
    MATCH(auction.field1, auction.field2) AGAINST ('search query' IN BOOLEAN MODE) OR 
    MATCH(auction.field3) AGAINST ('search query' IN BOOLEAN MODE) OR 
    MATCH(user.field1, user.field2, user.field3) AGAINST... 

:

bottomline MATCH() madde başına bir tek tam dizini kullanmak üzere aramanızı bölmek gerektiğidir user numaralı telefondan. Bunu gerçek yapınıza uyarlamanız gerekir (daha fazla rehberliğe ihtiyacınız varsa lütfen tablolarınızın açıklamalarını gönderin).

Bu durumun sadece InnoDB tablolarına uygulandığına dikkat edin. İlginç bir şekilde, MyISAM tabloları do not seem to show the same limitation.


Güncelleme: bu 5.6.13/5.7.2 giderilen, a bug in the InnoDB engine oldu çıkıyor. Yukarıdaki örnek, "Sütun listesiyle eşleşen FULLTEXT dizinini bulamıyor" şeklinde haklı olarak başarısız. Gerçekten de (f1, f2) üzerinde bir indeks yok, ancak bir tane (f1) ve diğeri (f2). As the changelog advises:

MyISAM farklı olarak, InnoDB'nin eklenmemiş sütunlar boole tam metin arama desteklemez, ancak bu bir kısıtlama hatalı sonuçlar sorguları sonuçlanan uygulanmamıştır.

Böyle sorgular MyISAM ile belirlenen doğru bir sonuç döndürmek iken, onlar they silently ignore existing fulltext indexes gibi bir beklediğinizden daha yavaş çalışabilir olması dikkat çekicidir. (Mod belirtildiğinde yani.) Ararken

+0

Bu kelimeden sonra bir şey elde etmek için * kullanabilirim, ancak arama sorgusunun kelimenin ortasında başlayabildiği kelimeleri elde etmenin bir yolu var mı? Örneğin: query = pple döndürme sonuçları 'apple' – puks1978

+0

Aşağıdaki gibi bir arama koşulu kullanabilirsiniz: "... Alan LIKE '% pple'' (' '' joker karakterdir) ancak böyle bir sorgu bir tam metin dizini kullanamaz (ya da normal bir indeks). "[MySQL, sütunlar dizinin en soldaki önekini oluşturmazsa bir dizin kullanamaz] (http://dev.mysql.com/doc/refman/5.6/en/mysql-indexes.html)" (başlangıçta çok sütunlu dizinleri tanımlamak amaçlanmış, ancak kısmi bir dizin için gerçekten aynı fikirdir). – RandomSeed

+0

Birden fazla eşleme kullanmanız için öneriniz ... ya da eşleşme ... 'bölümlerinde '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' 'myisam' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' yi de engellemekte gibi görünmektedir Bir sendika ile bağımsız sorgular daha iyi çalışır. E, g, 'rsspodcastitems 'ten (" sebze ") aleyhine maçın ya da (" sebze ") aleyhine altyazının eşleştiğini seçin ->> 16 satır set (2.46 sn)' iken,' rsspodcastitems 'den (maç başlığına karşı) "sebze") birliği rsspodcastitems'den * altyazısına ("sebze") karşılık gelen altyazıyı seçin -> 16 satır (0,02 sn). – Jules