扩展任意Lucene查询

时间:2012-12-05 01:14:35

标签: lucene

我正在使用Lucene 3.6.1。我收到用户的查询。此查询可能包含+-运算符,也可能包含短语。在某些情况下,我想通过添加一些我计算的额外术语来扩展查询。这些条款是可选的。但是,必须遵守用户指定的任何必需的包含/排除约束。

我的初始策略是创建一个BooleanQuery,向其中添加一个包含已解析用户查询的子句,然后添加包含我的扩展术语的其他子句。扩展条款将全部添加为Occur.SHOULD。我的问题是如何约束用户的查询。我可以想象三种可能性:

  1. 用户的查询不包含运算符,这意味着我可以将其包含为Occur.SHOULD子句。

  2. 用户的查询包含+运算符,因此我需要将其作为Occur.MUST子句包含在内。

  3. 用户的查询包含-运算符,但也包含其他术语:我是否仍将其作为Occur.MUST子句包含在内?

  4. 这三个选择中隐含的问题是如何判断哪种情况合适?我想我可以重写查询并测试BooleanQuery个实例,但这看起来很脆弱。

    我想也可以尝试从用户输入和扩展术语创建单个字符串的策略,如下所示:

    (fld1:userterm1 userterm2 -fld2:userterm3 +userterm4)^10 (fld1:expterm1)^8 (fld2:expterm2)^7 ...
    

    这是最好的方式吗?还是有一些优雅的程序化解决方案?

1 个答案:

答案 0 :(得分:0)

好的,不知道这个答案有多么有用,但似乎无法在这里找到一个快速的答案,所以我会列出一些可能的想法:

首先,一个问题:

将查询修改为:

(userquery) (other) (stuff)

我根据你所显示的规则添加+是有道理的,但是' - '禁止的术语将难以正确尊重,因为(query -prohibition) (other)将允许其他禁止存在的匹配,并且+(query -prohibition) (other)将要求“查询”匹配。

我认为真正做到这一点的唯一方法是将禁用的术语传播到您自动添加的术语中,或者将其提取到父查询层,更像是(query -prohibition) - > (query) (other) -(prohibition)

由于用户输入了任意复杂性的查询,这可能不是一个好策略。


如果您想通过修改查询字符串来解决它,那么您应该只是在查询结尾添加任何术语。没有更多的东西。

我不相信

(fld1:userterm1 userterm2 -fld2:userterm3 +userterm4)^10 (fld1:expterm1)^8 (fld2:expterm2)^7 ...

令人满意,因为userterm4仅在其子查询中是必需的,但匹配仅在expterm1上仍然可以接受。但是,查询如下:

fld1:userterm1 userterm2 -fld2:userterm3 +userterm4 (fld1:expterm1)^.8 (fld2:expterm2)^.7 ...

我认为应该满足您的需求,并且不必担心您的queryparser内部。 我认为这是最好的方法。


我还可以在像

这样的查询中看到逻辑
+(parsed userquery) (other stuff)

实际上,总是需要匹配用户查询。在某种意义上,Lucene隐含地这样做,因为即使查询中不存在必需的字段,它也不会返回不匹配任何术语的结果。然后,这将使用您添加的术语来影响评分,而不是返回更多的文档。这并没有完全解决你的要求,但可能值得考虑。


如果尽管存在上述应用它们的问题,你仍然想要检测'+'和' - '运算符,我认为可以合理地假设一个StandardQueryParser将在基类级别为你需要的任何查询返回一个BooleanQuery检查这些操作数。您可能不得不担心,例如,DisjunctionMaxQueries,以及当您使用运算符进行简单查询时会发生什么,例如:

+myterm

我不知道QueryParser是否会简单地返回一个TermQuery,从而失去了加号(因为如果不存在另一个术语,它将是多余的)。这样的担忧让我对以这种方式解决它犹豫不决。

同样,尝试从查询字符串中检测这些值必须对事物的解析方式做出假设,并且可能会变得复杂。


要进行sumamrize,我认为最好的选择是:在执行任何解析之前将术语添加到原始查询字符串的末尾,或者将用户查询视为原子,并在添加时定义相应的booleanclause,使其独立于内容使用布尔子句将其包装为您需要包含的任何其他查询。