簡體   English   中英

MySQL-優化查詢並返回更具體的匹配項

[英]MySQL - Optimizing my query and returning the more specific match

我不久前發布了一個問題,詢問如何使用以下條件實施搜索:

On the "Searching" page, the customer can search for movies by any of the following attributes or their combination (logical "AND" operation):
title;
year;
director;
star's first name and/or last name. This means you need to do both: a) first name or last name if only one of the two names is provided; b) first name and last name, if both names are provided.

然后,根據搜索輸入,我必須從數據庫中吐出有關該電影的信息。 人們建議我使用全文搜索,但是我做到了。 這是我想出的解決方案。

  String searchInput = request.getParameter("searchInput");
  String query = "";

  // First see if there is a number in their search
  // Note: doesn't consider more specific searches, because it only searches
  // based on the given number
  if (searchInput.matches("\\d+")) {
      Pattern p = Pattern.compile("\\d+");
      Matcher m = p.matcher(searchInput); 
      if (m.find()) {
          String number = m.group();
          int n = Integer.parseInt(number);
          query = "SELECT title, year, director, id " +
          "FROM movies " + 
          "WHERE year = " + n + " " +
          "OR title LIKE '%" + n + "%'";
      }
  } else {
      query = "SELECT title, year, director, r.id " +
      "FROM movies AS r, stars AS s " + 
      "WHERE MATCH(title, director) AGAINST('" + searchInput + "*') " + 
      "OR MATCH(first_name, last_name) AGAINST('" + searchInput + "*') " +
      "AND r.id IN (SELECT sim.movie_id " + 
                    "FROM stars_in_movies AS sim " + 
                    "WHERE sim.star_id = s.id " + 
                    "AND sim.movie_id = r.id) " +
      "GROUP BY title";
  }

  ResultSet rs = statement.executeQuery(query);

  // Query again, this time ANDing the matches to see if
  // there is a more specific search result
  Statement statement2 = dbcon.createStatement();
  query = "SELECT title, year, director, r.id " +
  "FROM movies AS r, stars AS s " + 
  "WHERE MATCH(title, director) AGAINST('" + searchInput + "*') " + 
  "AND MATCH(first_name, last_name) AGAINST('" + searchInput + "*') " +
  "AND r.id IN (SELECT sim.movie_id " + 
                "FROM stars_in_movies AS sim " + 
                "WHERE sim.star_id = s.id " + 
                "AND sim.movie_id = r.id) " +
  "GROUP BY title";

  ResultSet rs2 = statement2.executeQuery(query);
  if (rs2.next()) {
      // If there is a more specific match (ANDing the matches), use that instead
      rs2.beforeFirst();
      rs = rs2;
  }

現在,我知道這是非常糟糕的代碼,因為我執行了幾乎相同的查詢兩次,唯一的區別是我和第二個查詢中的匹配項。 我似乎無法找出一種方法來組合兩個查詢或減少匹配量以加快查詢速度。 對於用戶可能輸入或未輸入的電影年份,我也沒有很好的方法。

這是我嘗試過的:

  1. 我嘗試在FullText Search文檔中搜索一些可以包含在我的搜索中的函數,以使我的SQL查詢在匹配更多內容時返回更具體的結果,但是最接近這種情況的是Boolean Full。 -文本搜索。 但是,我認為我不能使用這樣的功能,因為我必須區分不同用戶的關鍵字輸入。

  2. 我還嘗試了在MySQL中使用Google的AND / OR操作,該操作允許在可能的情況下進行AND操作,如果不可能,則對查詢執行OR操作。 但是,似乎不可能做到這一點。

更新:我現在嵌套了子查詢,搜索速度更快。 但是,我仍然需要幫助改進我的代碼以返回更具體的匹配,並且僅返回更具體的匹配(如果存在)。 否則,返回更一般的匹配項(如果所有匹配項都存在)。

分別運行每個子查詢。 假設結果的大小合理,則可以根據需要對代碼進行AND和OR運算。 更多的編碼,但是您只運行必要的查詢一次。

暫無
暫無

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

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