MySQL>>逗号分隔标签上的自定义站点搜索没有多对多表

时间:2017-11-01 06:24:53

标签: mysql search tags wildcard sql-like

我开发了教育资源的内容门户,我需要为用户提供自定义搜索工具。

所有资源都存在于Resources表中。该表包含一个名为“RES_Tags”的字段,其中包含该资源的逗号分隔的标记(关键字)列表。

关于环境资源的RES_Tags字段中的数据示例可能是“环境,自然,地球,全球变暖,气候变化,污染,海洋,森林,雨林,采矿,森林砍伐”。

我需要一个SQL搜索查询策略,允许用户输入搜索字符串并获取其标记在精神上匹配的记录(即,不一定相同)。

所以,例如:

  • 搜索“ocean”的用户应获取带有该标记的所有记录 RES_Tags字段中的“海洋”。
  • 搜索“ocean”的用户应获取带有复数“海洋”标记的所有记录。
  • 搜索“海洋”的用户应获取包含“海洋”一词的所有记录,例如(“海洋捕捞”,“太平洋海洋”或“海洋酸化”)
  • 搜索“海洋酸化”的用户应获取所有记录 标签为“ocean”或标签“acidification”或标签“ocean” 酸化”。
  • 搜索“海洋”的用户不应获得标记中嵌入“海洋”的任何记录(“interocean”,“suboceans”,“oceanic”等),但复数“海洋”除外。虽然看起来在这种情况下会有意义,但我们不希望搜索词“art”返回记录,因为它们标记为“Jimmy Carter”
  • 如果搜索“海洋”返回的记录中包含与“海洋”,“水”,“海洋”等海洋相关的标记,那将是真棒和魔法(但根本没有必要)。

查询需要包含对逗号的理解,以便搜索“海洋,海洋生物,海洋”返回带有“海洋”,“海洋”和“海洋生物”标签的记录。

查询还需要包括对引号的理解,以便搜索“海洋生物”(引号)仅返回带有“海洋生命”标记的记录,而不返回仅具有“海洋”或“生命”的记录。

到目前为止,这是我正在使用的解决方案:

    IF InStr(1,Request.Form("SearchString")," AND ",1) > 0  OR InStr(1,Request.Form("SearchString")," OR ",1) > 0 THEN

        IF InStr(1,Request.Form("SearchString")," OR ",1) > 0 THEN
        searchArray_4 = Split(Request.Form("SearchString"),"OR",-1,1)
        FOR EACH x IN searchArray_4
            'Response.Write("OR split: "& x)
            strHRE_SqlStr_WHERE = strHRE_SqlStr_WHERE & "RES_Tags LIKE '%"& Trim(x) &"%' OR "
        NEXT

        strHRE_SqlStr_WHERE = strHRE_SqlStr_WHERE & ") OR "
        strHRE_SqlStr_WHERE = strHRE_SqlStr_WHERE & "("
        END IF
        IF InStr(1,Request.Form("SearchString")," AND ",1) > 0 THEN
        searchArray_5 = Split(Request.Form("SearchString"),"AND",-1,1)
        FOR EACH x IN searchArray_5
            'Response.Write("AND split: "& x)
            strHRE_SqlStr_WHERE = strHRE_SqlStr_WHERE & "RES_Tags LIKE '%"& Trim(x) &"%' AND "
        NEXT
        END IF
    ELSE
        searchArray_1 = "%"& Request.Form("SearchString") &"%"
        strHRE_SqlStr_WHERE = strHRE_SqlStr_WHERE & "RES_Tags LIKE '"& searchArray_1 &"' OR "

        strHRE_SqlStr_WHERE = strHRE_SqlStr_WHERE & ") OR "
        strHRE_SqlStr_WHERE = strHRE_SqlStr_WHERE & "("

        searchArray_2 = Split(Request.Form("SearchString"))
        FOR EACH x IN searchArray_2
            strHRE_SqlStr_WHERE = strHRE_SqlStr_WHERE & "RES_Tags LIKE '%"& Trim(x) &"%' OR "
        NEXT

        strHRE_SqlStr_WHERE = strHRE_SqlStr_WHERE & ") OR "
        strHRE_SqlStr_WHERE = strHRE_SqlStr_WHERE & "("

        searchArray_3 = Split(Request.Form("SearchString"),",")
        FOR EACH x IN searchArray_3
            strHRE_SqlStr_WHERE = strHRE_SqlStr_WHERE & "RES_Tags LIKE '%"& Trim(x) &"%' OR "
        NEXT

    END IF 

我确信这种方法是一种业余的黑客行为,我将非常感谢看看是否有更好的解决方案。

顺便说一句,这里有一个类似的问题(php/mysql: Custom site search),我已经阅读了,我想使用一个不涉及规范化RES_Tags字段的解决方案(如果可能的话)。所以,我把它写成一个不同的问题。希望没关系。

0 个答案:

没有答案