如何在SQLITE中进行多词部分搜索?

thtygnil  于 2023-10-23  发布在  SQLite
关注(0)|答案(1)|浏览(145)

你好,我想写一个多字部分搜索在SQLITE:

  • 如果用户键入red,则我将给予在其名称或其颜色或React性中具有红色的所有抗体,
  • 如果用户类型red 20我想给予交叉抗体与红色和20在他们的名字或他们的颜色或React。

我已经写了这个,但我认为SQL中应该有一些东西可以让它更容易。

const searchMultiWord = (
      index: number,
      amount: number,
      information: string[],
      startDate: number,
      endDate: number,
    ) => {
      return new Promise<Antibodies[]>((resolve, reject) => {
        let antibodies: Antibodies[] = [];
        let totalCount: number;
        let defaultSql = `SELECT id, name as antibodyName 
                              FROM Antibodies 
                              WHERE id IN (
                                SELECT id FROM
                                (
                                  SELECT id FROM Antibodies WHERE name LIKE ?
                                  UNION all
                                  SELECT antiId FROM AssignedColors WHERE name LIKE ?
                                  UNION all
                                  SELECT antiId FROM AssignedReactivities WHERE name LIKE ?
                                )`;
        let defaultParams = [`${startDate}`, `${endDate}`, `${amount}`, `${index}`]
        for (let i = 0; i < information.length - 1; i++) {
          defaultSql += `INTERSECT
          SELECT id FROM
          (
            SELECT id FROM Antibodies WHERE name LIKE ?
            UNION all
            SELECT antiId FROM AssignedColors WHERE name LIKE ?
            UNION all
            SELECT antiId FROM AssignedReactivities WHERE name LIKE ?
          )`;
          defaultParams.unshift(`%${information[i]}%`, `%${information[i]}%`, `%${information[i]}%`);
        }
        defaultParams.unshift(`%${information[information.length - 1]}%`, `%${information[information.length - 1]}%`,
          `%${information[information.length - 1]}%`);
        defaultSql += `) AND dateOfCreation >= ? AND dateOfCreation <= ?
        ORDER BY dateOfCreation DESC LIMIT ? OFFSET?;`;
        db.serialize(() => {
          db.each(defaultSql,
            defaultParams
            , (err, antibody) => {
              if (err) {
                return err.message;
              } else {
                db.all('SELECT name, locations, colorId FROM AssignedColors WHERE antiId = ?', [antibody.id], (err, colors) => {
                  if (err) {
                    reject(err.message)
                  } else {
                    antibody.colors = colors;
                    antibodies.push(antibody);
                    if (totalCount === antibodies.length) {
                      resolve(antibodies);
                    }
                  }
                });
              }
            }, (err, count) => {
              if (err) {
                reject(err.message)
              } else {
                if (count === 0) {
                  resolve(antibodies);
                } else {
                  totalCount = count;
                }
              }
            });
        });
      });
    }
vybvopom

vybvopom1#

为您想要搜索的值创建一个CTE,如'red''20',以及另一个CTE,它返回所有3个表的列idname
连接表group by id并在HAVING子句中设置条件:

WITH 
  search(val) AS (VALUES ('red'), ('20')), 
  cte AS (
    SELECT id, name FROM Antibodies
    UNION ALL
    SELECT antiId, name FROM AssignedColors
    UNION ALL
    SELECT antiId, name FROM AssignedReactivities
  )
SELECT c.id
FROM cte c INNER JOIN search s
ON c.name LIKE '%' || s.val || '%'  
GROUP BY c.id
HAVING COUNT(DISTINCT s.val) = (SELECT COUNT(*) FROM search)

相关问题