2010-11-19 18 views
15

Üç ayrı tabloda tam metin araması yapmaya çalışıyorum ve sonuçları alaka düzeyine göre sıralıyorum. Yanıt için yaptığım aramalarda, birden fazla tabloda tam metin araması kullanamayacağımı öğrendim. Bu yüzden aramak istediğim her sütun için ayrı bir tam metin dizini ekledim. Şimdi sorun şu ki aramayı yapabilirim ama istediğim gibi sıralayamıyorum.Birden çok tablodaki mysql tam metni

İşte benim tablolar

CREATE TABLE books (
bookID int(11) NOT NULL AUTO_INCREMENT, 
title varchar(300) NOT NULL, 
authorID int(11) NOT NULL, 
FULLTEXT KEY title (title) 
) 

CREATE TABLE IF NOT EXISTS authors (
authorID int(11) NOT NULL AUTO_INCREMENT, 
authorNamevarchar(200) NOT NULL, 
FULLTEXT KEY authorName(authorName) 
); 

CREATE TABLE IF NOT EXISTS chapters (
chapterID int(11) NOT NULL AUTO_INCREMENT, 
bookID int(11) NOT NULL, 
content longtext NOT NULL, 
FULLTEXT KEY content (content) 
); 

Ve sql sorgusu var. Bu benim sıkıştığım yer.

SELECT *, 
MATCH(books.title) AGAINST('$q') as tscore, 
MATCH(authors.authorName) AGAINST('$q') as ascore 
MATCH(chapters.content) AGAINST('$q') as cscore 
FROM books 
LEFT JOIN authors ON books.authorID = authors.authorID 
LEFT JOIN chapters ON books.bookID = chapters.bookID 
WHERE 
MATCH(books.title) AGAINST('$q') 
OR MATCH(authors.authorName) AGAINST('$q') 
OR MATCH(chapters.content) AGAINST('$q') 
ORDER BY ???? DESC 

Artık bu sorgu ile başlıklar, yazarlar veya içeriklere göre sıralama yapabilirim. Yapmak istediğim, üç sütunun hepsinin alaka düzeyini bir araya getirip sonuçları ona göre sıralamasıdır.

Ve evet, ben lucene veya sfenks gibi diğer arama motorlarının farkındayım, ama şimdi onları kullanmayı planlamıyorum.

Şimdiden teşekkürler.

cevap

30

ORDER BY yan tümcesinde tscore, ascore ve cscore değerlerini ekleyebilmeniz gerekir.

bu deneyin:

SELECT *, 
MATCH(books.title) AGAINST('$q') as tscore, 
MATCH(authors.authorName) AGAINST('$q') as ascore, 
MATCH(chapters.content) AGAINST('$q') as cscore 
FROM books 
LEFT JOIN authors ON books.authorID = authors.authorID 
LEFT JOIN chapters ON books.bookID = chapters.bookID 
WHERE 
MATCH(books.title) AGAINST('$q') 
OR MATCH(authors.authorName) AGAINST('$q') 
OR MATCH(chapters.content) AGAINST('$q') 
ORDER BY (tscore + ascore + cscore) DESC 
+1

ikinci sorgusu ile aynı şeyi yapar. Teşekkürler. – keune

+0

Yükler bana yardımcı oldu. Teşekkürler! – youngcouple10

+1

Çok güzel, projem için neye ihtiyacım vardı! – NaturalBornCamper

-1

Bu, sıralamak istediğiniz şeye bağlıdır. Yazar, daha sonra başlık, bu

ORDER BY MATCH(authors.authorName) DESC ,MATCH(books.title) DESC ,MATCH(chapters.content) DESC 

fikir yazarlar adını bulduğunda, onu sırayla oranla daha ilgili olduğu başlık, bulunan zamanla kıyaslandığında daha alakalı olduğunu olmakla ardından bölüm içeriği göre sıralamak olabilir bölüm metninde bulmak. Ayrıca

ORDER BY MATCH(authors.authorName) + MATCH(books.title) + MATCH(chapters.content) DESC 

ile toplam alaka göre sıralamak olabilir ama bu arama metni sadece başlık önce ortaya çıkabilir bölüm içeriğinde gösterir şey olarak, garip sonuçlar verebilir.

+0

işe yaramadı .... tam olarak ikinci sorgu – ITECH

0

@Ike Walker'ın çözüm büyük, ancak benim durumumda ben arama sonucunda başına tek bir satıra bire çok sonuç sarmak istedi.

Şema:

T1: Articles 
T2: Comments (many comments to one article) 

endeksler:

ALTER TABLE articles ADD FULLTEXT title_index (title) 
ALTER TABLE articles ADD FULLTEXT body_index (body) 
ALTER TABLE comments ADD FULLTEXT comment_index (comment) 

SQL:

SELECT 
    articles.title, 
    SUM(MATCH(articles.title) AGAINST('$q') + 
    MATCH(articles.body) AGAINST('$q') + 
    MATCH(comments.comment) AGAINST('$q')) as relevance 
FROM 
    articles 
LEFT JOIN 
    comments ON articles.id = comments.article_id 
WHERE 
    MATCH(articles.title) AGAINST('$q') 
    OR MATCH(articles.body) AGAINST('$q') 
    OR MATCH(comments.comment) AGAINST('$q') 
GROUP BY 
    articles.id 
ORDER BY 
    relevance DESC 

Not: İsterseniz @Ike Walker'ın çözümü riffing burada işin yapılması böyle kazandım Her alana ağırlık eklemek gibi bir şey yapabilirsiniz.

SUM((MATCH(articles.title) AGAINST('$q')*3) + 
     (MATCH(articles.body) AGAINST('$q')*2) + 
     MATCH(comments.comment) AGAINST('$q')) as relevance 

Bu durumda başlık, yorumlarda bir eşleşme değeri olan 3x, beden 2x değerine sahip olacaktır.

İlgili konular