我正在使用MarkLogic 9开发一个基于web的搜索应用程序,我有一个查询构建界面,允许用户将字符串输入到文本框中,这些文本框对应于数据库中文档的特定JSON属性。这样做的想法是用户可以按照cts.parse (我使用服务器端javascript而不是XQuery)所期望的那样输入搜索词,这样他们的搜索就可以任意复杂,我就不必自己解析查询了。然而,在做了一些测试之后,我发现了一个关于布尔逻辑中使用括号的奇怪现象。也就是说,当您在如cat和(狗或鸟)这样的语句中包含括号时,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)], [])
这个方法正确地为"brain“项生成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还是绑定对象?
任何帮助都将不胜感激。
发布于 2017-07-24 22:24:38
我不清楚您确切的查询字符串是什么。
如果查询字符串类似于"main:(cat OR dog)",则OR不是该上下文中的关键字。标记之后允许的内容是相当有限的,并不是所有的查询语言,它只是一个文本列表。
如果查询字符串类似于"main:cat OR dog,那么标记的作用域就是cat。
现在您可以将一个函数绑定到标记上(当它被固定到一个范围索引或字段时),希望标记后面的()对整个查询进行作用,这不是不合理的,但语法不是这样设置的。
所以你只需要做一些零碎的事情:main:cat OR main:dog
或者:给定传递到函数中的一组值,空间连接它们并将它们传递给单独的cts:parse调用,以便将它们解释为可以包装的查询。
发布于 2017-07-25 05:27:07
正如玛丽所解释的,你应该把main:cat OR dog理解为(main:cat) OR dog。您可以像Erik建议的那样,在解析之前重写查询到main:cat OR main:dog,或者您可以解析cat OR dog (没有前缀),然后对cts:查询树进行后处理,以扩展cts:word查询与您要查找的三个-部分或-查询的匹配项。使用类型转换器的递归函数应该能做到这一点。
哈哈!
https://stackoverflow.com/questions/45290310
复制相似问题