首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何分解搜索查询

如何分解搜索查询
EN

Stack Overflow用户
提问于 2012-03-27 14:17:50
回答 3查看 353关注 0票数 1

我正在为CCG开发一个搜索引擎。我希望用户能够找到基于查询的卡,如"blue brigade hero enhancements that can discard ec's""purple kings of israel"。有许多变量可以搜索:旅(紫色,蓝色),类型(英雄,邪恶人物ec),特殊能力(丢弃)和身份(以色列国王)。我正在考虑使用正则表达式来查找通用的搜索参数。我知道这并不容易,而且需要很长时间才能进行微调,但是有人能给我指出正确的方向吗?正则表达式是一个推荐的解决方案吗?我不知道这是否重要,但我使用的是php和mysql。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-03-29 15:39:37

您必须编写一个解析器来解析这样的查询字符串。

正则表达式对于在查询字符串中查找“verbs”和“nouns”很有用,但您可能还需要一个描述查询语言的非上下文语法,例如:

代码语言:javascript
运行
复制
<QUERY> := <TARGET_SPEC>
<TARGET_SPEC> := <OBJECT> 'that can' <ABILITY>
<TARGET_SPEC> := <OBJECT>  
<OBJECT> := <COLOR> <WHAT> 
<OBJECT> := <WHAT>
<COLOR> := 'blue' | 'red' | 'purple' | 'green' 
<WHAT> := <ITEM> | <HERO>
<ITEM> := <ADJECTIVE> <ITEM>
<ADJECTIVE> := 'brigade' | 'hero' | 'magic' | 'enhanced' | 'rustproof'
<ITEM> := 'enhancements' | 'sword' | 'potion'
<HERO> := <HERO> 'of' <COUNTRY>
<HERO> := 'kings' | 'knights' | 'thiefs'
<COUNTRY> := 'israel' | 'palestine' | 'jordan' | 'egypt'
<ABILITY> := <ABILITY> 'and' <ABILITY>
<ABILITY> := 'swim' | 'dance' | discard <DISCARDABLE> | 'kill' <HERO> | 'use' <ITEM>
<DISCARDABLE> := 'ec's' | 'et's' | 'etc'

基于这样的语法构建的解析器将能够确定查询的哪个部分是对象,这是一种能力,颜色,国家等。例如,给定输入字符串‘红色的约旦骑士,可以游泳’,解析器将选择正确的规则并应用它们:

代码语言:javascript
运行
复制
<QUERY> := 'red knights of jordan that can swim'
<TARGET_SPEC> := 'red knights of jordan that can swim'
<TARGET_SPEC> := 'red knights of jordan' 'that can' 'swim'
<OBJECT> := 'red knights of jordan'
<ABILITY> := 'swim'
<COLOR> := 'red'
<WHAT> := 'knights of jordan'
<HERO> := 'knights' 'of' 'jordan'
<HERO> := 'knights'
<COUNTRY> := 'jordan'

基于提取的信息,您将能够创建搜索条件。

使用语法还有一个额外的好处,那就是解决了一些其他方法很难解决的歧义--例如,如果用户要求“可以杀死白衣骑士的红色国王”,那么通过将每个单词与可用的颜色列表进行匹配来查找颜色的简单算法将会失败。

我推荐阅读一本关于编译器设计的书-- Dragon Book是一个经典的选择(你不必全部阅读,只需要阅读关于词法分析器和解析器的部分)。

如果您不想自己编写整个解析器(因为这可能非常耗时且容易出错),那么您将需要一个解析器生成器(即,一个为给定语法创建解析器源代码的程序);here是一个有一些建议的问题。

您还应该考虑阅读有关自然语言处理技术的书籍。斯坦福大学here有一门在线课程,我现在正在“参加”它,我可以全心全意地推荐它。

票数 7
EN

Stack Overflow用户

发布于 2012-03-29 16:33:51

我真的很喜欢socha's suggestion,但我也会考虑一个简单得多的。

如果您有一个已知搜索词的字典,并且能够纠正它们的语法和语法(提示:使用您的数据库和OED作为缓存层,在Google上抛出任何缓存未命中),您可以通过将每个搜索词binary bucket sorting到已知类型的集合中来执行搜索。使用您的示例,每个存储桶将是: brigade_purple,brigade_blue,type_hero,type_evil,您的每个特殊能力,以及您的每个特殊类型标识符。

对于每张卡,构造一个符合您的存储桶的位域。对于每个用户查询,构造相同的查询。然后,通过执行数据库的逐位遍历返回符合您的位掩码的结果,对于这个玩具示例,我假设它的形状类似于B+ tree,按照最接近掩码的结果按主位顺序排序。这样做的好处是可以扩展到支持位字段的最大长度,这在许多数据库实现中实际上是无界的。

好的,这有点技术性。这就是我在任何情况下构建搜索数据库的方式。

票数 0
EN

Stack Overflow用户

发布于 2012-03-30 00:58:36

使用TierTempCur作为

代码语言:javascript
运行
复制
--/*Use Rela table to get the offspring of the parent*/ 

        (
            SELECT Rela.ID_RSSD_PARENT
                , Rela.ID_RSSD_OFFSPRING
                , '12/31/2011' AS REPORT_DATE
                , 1 As TREE_LVL 
                , CHECKSUM(ID_RSSD_PARENT, ID_RSSD_OFFSPRING) As CHKSUM 
                , RIGHT('000000000'+ CONVERT(VARCHAR(MAX),ID_RSSD_OFFSPRING),9) AS RSSD_PATH 
            FROM CUV_RELATIONSHIPS As Rela
            WHERE ID_RSSD_PARENT = 451965 AND '12/31/2011' BETWEEN D_DT_START AND D_DT_END 
                AND Rela.CTRL_IND = 1      --/* indicates subsidiary */
                AND Rela.OTHER_BASIS_IND not in (3,8)  --/* Per DM's job */

            UNION ALL

            SELECT Rela.ID_RSSD_PARENT
                , Rela.ID_RSSD_OFFSPRING
                , REPORT_DATE
                , TREE_LVL + 1 As TREE_LVL
                , CHECKSUM(Rela.ID_RSSD_PARENT, Rela.ID_RSSD_OFFSPRING) As CHKSUM 
                , Tmp.RSSD_PATH + '\' + RIGHT('000000000'+ CONVERT(VARCHAR(MAX),Rela.ID_RSSD_OFFSPRING),9) AS RSSD_PATH 
            FROM CUV_RELATIONSHIPS As Rela
            INNER JOIN TierTempCur As Tmp 
              ON Rela.ID_RSSD_PARENT = Tmp.ID_RSSD_OFFSPRING
              AND REPORT_DATE BETWEEN Rela.D_DT_START AND Rela.D_DT_END
            WHERE TREE_LVL < 20          --/*max depth for the tier is 20 -- to end self referencing parent/child relationships */
              AND Rela.CTRL_IND = 1      --/* indicates subsidiary */
              AND Rela.OTHER_BASIS_IND not in (3,8)
        ),
票数 -2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9884287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档