MarkLogic 9 cts.parse无法正确解析查询

时间:2017-07-24 21:23:31

标签: javascript marklogic marklogic-9

我正在使用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)

以下是输入的字符串和返回的查询的一些示例:

  1. 脑或心脏或肺
  2. 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()

    1. 大脑或心脏和肺
    2. 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"])], [])

      1. 脑OR(心肺)
      2. 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,但其他术语作为基本单词查询,我试图避免。

        1. (脑或心脏)和肺
        2. 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或绑定对象?

          非常感谢任何帮助。

2 个答案:

答案 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!