我试图制作一个搜索栏,该栏根据所使用的字符串不断缩小数据库中的行。我希望能够使我的搜索包含多个单词,并使每个单词搜索不同的列。
example.db
Make Model Year
------ ------ ------
Toyota Corolla 2000
Toyota Corolla 2002
Toyota Camry 2000
Toyota Camry 2002
Honda Civic 2002
这是我到目前为止所拥有的...
@app.route("/search")
def search():
q = request.args.get("q") #q is a string containing make, model, and/or year
car = db.execute("SELECT * FROM places WHERE Make LIKE :q\
OR Model LIKE :q\
OR Year LIKE :q, q=q+"%")
现在,如果我仅搜索一列,则此方法有效。如果我有/ search?q = corolla,它将选择带有模型花冠的两行。如果我有/ search?q = toyota + corolla,则不会选择任何行,因为没有单列具有Toyota花冠。
我想这样做,以便我输入q的信息越多,搜索结果的范围就越窄
即。
我已经搜索了一段时间,但似乎无法正确表达我的问题。到目前为止,我已经尝试过用空格分割字符串并查询每个单词,但这与分别搜索它们相同。我还尝试在q前面添加通配符,但这根本解决不了在搜索中包含多个单词的问题。我完全被那种简单的感觉所困扰。如果重要的话,输入将始终按品牌,型号,年份的顺序进行。任何帮助表示赞赏。
答案 0 :(得分:0)
您正试图以错误的方式解决全文搜索问题。我强烈建议您使用数据库提供的全文搜索功能,而不要与列进行比较。请参阅sqlite3 here中FTS的实现。
答案 1 :(得分:0)
我建议您使用全文搜索-假设您要查找全文。但是您可以使用like
进行此操作。只是用另一种方式进行比较:
WHERE :q LIKE '%' || Make || '%' OR
:q LIKE '%' || Model || '%' OR
:q LIKE '%' || Year || '%'
如果您需要所有单词都匹配,那么您可以通过以下方式接近:
WHERE ( (CASE WHEN :q LIKE '%' || Make || '%' THEN 1 ELSE 0 END) +
(CASE WHEN :q LIKE '%' || Model || '%' THEN 1 ELSE 0 END) +
(CASE WHEN :q LIKE '%' || Year || '%' THEN 1 ELSE 0 END)
) = <# of words in :q>
这并不确切,但是对于您的目的而言可能就足够了。
答案 2 :(得分:0)
我相信,如果给定参数为null,则这种情况基本上应该返回省略过滤器。...
WHERE
(Make = @Make OR CASE WHEN @Make IS NULL THEN 1 ELSE 0 END = 1)
AND
(Model = @Model OR CASE WHEN @Model IS NULL THEN 1 ELSE 0 END = 1)
AND
(Year = @Year OR CASE WHEN @Year IS NULL THEN 1 ELSE 0 END = 1)