簡體   English   中英

MySQL全文搜索並按相關性和時間排序

[英]MySQL fulltext search and sort by relevance + TIME

我試圖在我的網站上顯示“相關文章”塊。 為此,我使用以下查詢:

SELECT *, MATCH(title, content) AGAINST('search string') AS score 
FROM news_items 
WHERE MATCH(title, content) AGAINST('search string') 
ORDER BY score DESC LIMIT 4

但是,它經常顯示非常老的文章,而我想顯示最新的文章,因此我將查詢固定如下:

SELECT *, MATCH(title, content) AGAINST('search string') AS score 
FROM news_items 
WHERE MATCH(title, content) AGAINST('search string') > 4 
ORDER BY ctime DESC, score DESC LIMIT 4

但是在這種情況下,我收不到最相關的文章:(

有關如何同時找到最相關和最新鮮的文章的任何想法?

提前致謝!

您可以更改為總分...類似這樣:


SELECT *, 
  (
    MATCH(title, content) AGAINST('search string')
    - 
    (ABS(DATEDIFF(`timestampfield`, NOW())) / 365)
  ) AS score 
FROM news_items 
WHERE 
  MATCH(title, content) AGAINST('search string') > 4 
ORDER BY score DESC LIMIT 4

在其中有一種時髦的添加,您需要清理:

- (ABS(DATEDIFF(`timestampfield`, NOW())) / 365)

這是您分數的age部分...目前按<year> = 1 point

為此,我們首先獲取時間戳字段與現在之間的天數(絕對值):

ABS(DATEDIFF(`timestampfield`, NOW()))

然后我們擴展...

我決定您可能不想根據天數來降低分數,因為如果某項內容已存在30天,那將是-30天……似乎太苛刻了。 因此,我選擇了幾年...如果要按周數擴展,請除以52而不是365 ...以此類推。

此縮放因子將是您如何控制得分匹配和年齡之間的值。

最終結果如下: <match score> - <yearsAgo>


如果您這樣做:

  1. 5(比賽得分)-0.1(<1年前)= 4.9 (正常比賽,但最新)
  2. 5(比賽分數)-0.01(<1年前)= 4.99
  3. 5(比賽得分)-1(1年之前)= 4
  4. 6(比賽得分)-2(2年前)= 4
  5. 9(比賽得分)-5(5年前)= 4 (最佳比賽,但歷史悠久)
  6. 7(比賽得分)-10(10年前)= -3

注意,這假設您的時間戳字段是完整的日期時間字段...否則,您將需要重新廣播到日期,或直接操作unix時間戳的邏輯。

這是查詢的調試版本:

SELECT
    `created`,
    MATCH(title, content) AGAINST('awesome') as match_score,
    (ABS(DATEDIFF(`created`, NOW())) / 365) as years_ago,
  (
    MATCH(title, content) AGAINST('awesome')
    - 
    (ABS(DATEDIFF(`created`, NOW())) / 365)
  ) AS score 
FROM news_items 
WHERE 
  MATCH(title, content) AGAINST('awesome') > 4 
ORDER BY score DESC LIMIT 4

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM