Java 从用户输入创建查询&;已知领域

Java 从用户输入创建查询&;已知领域,java,lucene,Java,Lucene,我试图用Java生成一个查询来搜索Lucene索引。有问题的记录有一个recordState字段,因此我从以下内容开始查询: BooleanQuery booleanQuery = new BooleanQuery(); booleanQuery.add(new TermQuery(new Term("recordState", "DRAFT")), Occur.MUST); 当我想添加用户提供的过滤器时,问题就来了。我已尝试将代码更改为: String userQuery = ""; //

我试图用Java生成一个查询来搜索Lucene索引。有问题的记录有一个recordState字段,因此我从以下内容开始查询:

BooleanQuery booleanQuery = new BooleanQuery();
booleanQuery.add(new TermQuery(new Term("recordState", "DRAFT")), Occur.MUST);
当我想添加用户提供的过滤器时,问题就来了。我已尝试将代码更改为:

String userQuery = ""; // This will be whatever the user types in
QueryParser queryParser = new QueryParser(Version.LUCENE_29, "", new StandardAnalyzer(Version.LUCENE_29,
  new HashSet<String>()));
BooleanQuery booleanQuery = new BooleanQuery();
booleanQuery.add(new TermQuery(new Term("recordState", "DRAFT")), Occur.MUST);
booleanQuery.add(queryParser.parse(userQuery), Occur.MUST);
String userQuery=”“;//这将是用户键入的任何内容
QueryParser QueryParser=新的QueryParser(Version.LUCENE_29,”),新的StandardAnalyzer(Version.LUCENE_29,
新的HashSet());
BooleanQuery BooleanQuery=新的BooleanQuery();
添加(新术语查询(新术语(“记录状态”、“草稿”)),出现。必须);
add(queryParser.parse(userQuery),occure.MUST);
如果用户输入
record\u id:123
作为他们的查询,我最终得到的查询将是
+recordState:DRAFT+record\u id:123
-很好。如果用户输入
+record\u id:123
,则最终查询为
+recordState:DRAFT+(+record\u id:123)
——虽然不理想,但可以正常工作

但是如果用户输入
-record\u id:123
,最后的查询是
+recordState:DRAFT+(-record\u id:123)
,这看起来无效&没有多大意义

有没有更好的方法来组合这两个查询部分?我不能将用户的查询附加为纯文本,就好像他们没有以+/-开头一样,查询将以
+recordState:DRAFT record\u id:123
(record state=DRAFT或record id)结束


我想我唯一能做的就是测试用户查询是否只包含一个术语&如果是,请删除任何前面的+/-。但是我希望在不进行任何字符串操作的情况下执行此操作&坚持使用Lucene API。

实际上,您提供的语法并没有那么严重的错误,但结果可能不像您预期的那样

查询:

-record_id:123
这不是很有用。Lucene不支持纯否定查询。Lucene需要搜索一些东西,如果只给它不匹配的东西,它将什么都不匹配

由于您的目标似乎只是过滤到只有
recordState
=
DRAFT
的文档,并且已经给出了一个有效的查询,因此不返回结果是合理的,因为用户输入的查询实际上并不好

类似以下的查询:

+recordState:DRAFT +(-record_id:123 anotherfield:terms)
很好,而且:

+recordState:DRAFT +(+record_id:123)
括号内的
+
实际上不是必需的,但它也可以正常工作

如果您希望通过分析查询字符串或迭代解析器返回的
BooleanQuery
来检测这样的纯负查询,例如:

BooleanQuery query = (BooleanQuery)parser.parse;
BooleanClause[] clauses = query.getClauses();
if (clauses.length == 1 && clauses[0].getOccur() == BooleanClause.Occur.MUST_NOT) {
    booleanQuery.add(clauses[0]);
} else {
    booleanQuery.add(query, BooleanClause.Occur.MUST);
}

这可能会处理非常具体的情况,但是请记住,如果用户可以创建任意复杂度的查询,那么他们也可以创建嵌套在查询中某处的相同问题。此外,查询解析器不保证返回
布尔查询,因此这是一种假设。

+recordState:DRAFT+(-record\u id:123)实际上,它说的没关系-显示记录,其中第一个和第二个查询匹配,其中第一个是术语查询,第二个是否定查询-显示除文档以外的所有内容,由该术语查询匹配。所以我不认为当前的方法有任何问题,尽管我会这样理解语法,但它并没有这样做
+recordState:DRAFT+(-record\u id:123)
+recordState:DRAFT-record\u id:123
不返回相同的结果:(是的,因为这是不同的查询。这几乎是我昨晚得出的结论。我没有看到我可以通过解析器从提供的子句中获得结果,所以这比我想做的字符串检查要好。