我正在使用MarkLogic 9开发基于Web的搜索应用程序。我有一个查询构建接口,允许用户将字符串输入到与db中文档的特定JSON属性相对应的文本框中。想法是用户可以输入搜索条件,就像cts.parse(我使用服务器端javascript,而不是XQuery)所期望的那样,因此他们的搜索可能是任意复杂的,我不必处理自己解析查询。然而,经过一些测试,我发现了一个关于在布尔逻辑中使用括号的奇怪现象。也就是说,当你在括号中添加像cat和(dog OR bird)这样的语句时,cts.parse会将OR误认为是搜索词。
我将从我的网站上提供一个实际的例子:
我构建了一个绑定对象来将查询绑定到我的文档元素
var qOpts = ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded"];
var bindings = {
main: function(operator, values, options){
return(
cts.orQuery([
cts.jsonPropertyWordQuery('title',values,qOpts),
cts.jsonPropertyWordQuery('abstract',values,qOpts),
cts.jsonPropertyWordQuery('meshterms',values,qOpts),
])
);
},
}
我的服务器端脚本调用,例如
cts.parse('main:'+params.mainQuery,bind)
以下是输入的字符串和返回的查询的一些示例:
cts.orQuery([cts.jsonPropertyWordQuery("title", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("abstract", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("meshterms", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.wordQuery("heart", ["lang=en"], 1), cts.wordQuery("lung", ["lang=en"], 1)], [])
这个正确地为“大脑”术语的3个字段(标题,摘要,网格术语)生成jsonPropertyWordQuery,但是对于其他两个术语没有这样做,它只是生成一个cts.wordQuery()
cts.orQuery([cts.jsonPropertyWordQuery("title", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("abstract", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("meshterms", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.andQuery([cts.wordQuery("heart", ["lang=en"], 1), cts.wordQuery("lung", ["lang=en"], 1)], ["unordered"])], [])
cts.orQuery([cts.jsonPropertyWordQuery("title", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("abstract", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("meshterms", "brain", ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.andQuery([cts.wordQuery("heart", ["lang=en"], 1), cts.wordQuery("lung", ["lang=en"], 1)], ["unordered"])], [])
2和3看起来是一样的。第一部分正确生成jsonPropertyWordQuery,但其他术语作为基本单词查询,我试图避免。
cts.andQuery([cts.orQuery([cts.jsonPropertyWordQuery("title", ["brain", "OR", "heart"], ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("abstract", ["brain", "OR", "heart"], ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1), cts.jsonPropertyWordQuery("meshterms", ["brain", "OR", "heart"], ["case-insensitive","punctuation-insensitive","whitespace-insensitive","wildcarded","lang=en"], 1)], []), cts.wordQuery("lung", ["lang=en"], 1)
这里,解析器似乎没有认识到OR是一个运算符,因为即使它正确生成了jsonPropertyWordQueries,它也会在搜索中包含OR作为一个术语。
老实说,我无法找到任何正确的查询,这让我相信我一定做错了。我不知道那可能是哪里。我是否误用了cts.parse或绑定对象?
非常感谢任何帮助。
答案 0 :(得分:7)
我不清楚你的确切查询字符串是什么。
如果查询字符串类似于"main:(cat OR dog)"
,则OR不是该上下文中的关键字。标签非常有限,并且不是查询语言的全部范围,它只是一个文字列表。
如果查询字符串类似于"main:cat OR dog
,则标记的范围仅为cat
。
在标记之后想要()后面的整个查询范围并不是没有道理的,现在你可以将一个函数绑定到标记(当它被固定到范围索引或字段时没有意义),但这不是语法是如何建立的。
所以你只需要零碎地做事:main:cat OR main:dog
或者:给定传递给函数的值集合,空间连接它们并将其传递给单独的cts:parse
调用,以将它们解释为可以包装的查询。
答案 1 :(得分:2)
正如Mary所解释的那样,您应该将main:cat OR dog
视为(main:cat) OR dog
。您可以执行类似Erik建议的操作,并在解析为main:cat OR main:dog
之前重写查询,或者您可以解析cat OR dog
(不带前缀),然后对cts:query树进行后处理以扩展cts:单词查询带有你所追求的三个或一些查询。使用typeswitch的递归函数应该可以解决这个问题。
HTH!