在MarkLogic中查询包含给定字符串的JSON属性值的文档

时间:2015-12-29 16:25:42

标签: java marklogic nosql

我正在使用MarkLogic 7.0,java-client-api 2.0.5。

让我们说,我有以下文件

{"id": 233457657, "message": "8=FIX.4.3 9=118 35=A 34=1 49=ABCMKD"}

我希望在将“34 = 1 49 = ABC”传递给查询以及具有此类子字符串的消息值的其他文档时选择它。我该如何构建查询?

我尝试了以下内容,但似乎并不符合我的期望:

new StructuredQueryBuilder().term("*" + substring + "*");

我知道这可能是一个非常基本的问题,但我对ML很新,并且对文档有点困惑。 谢谢!

2 个答案:

答案 0 :(得分:4)

通用索引存储属性值中的单词。默认情况下,单词是连续的数字或字母(即由空格或标点分隔)。

在上面的示例中,message属性的索引中的默认单词是:

8, FIX, 4, 3, 9, 118, 35, 1, 49, ABCMKD

您可以在消息属性中查询此类单词的相关组合,如:

qb.and(
  qb.word(qb.jsonProperty("message"), "34"),
  qb.word(qb.jsonProperty("message"), "1"),
  qb.word(qb.jsonProperty("message"), "49"),
  qb.word(qb.jsonProperty("message"), "ABCMKD")
  )

这可能会匹配许多您不感兴趣的消息。

使这些文档可查询的第一步是将消息字符串中隐藏的字段公开为JSON属性:

{"id": 233457657, "message": {
    "m8": "FIX.4.3",
    "m9": "118",
    "m35": "A",
    "m34": "1",
    "m49": "ABCMKD"
    }}

然后,您可以使用qb.value()查询单独匹配这些属性。

如有必要,您可以配置数据库以支持这些属性值的通配符。

最后,如果可能的话,您应该升级到MarkLogic 8,它本身支持JSON。 MarkLogic 6和7通过对XML的内部转换支持JSON,但效果不佳。

除了回应评论......

如果上面显示的和相关的单词查询偶尔出现误报,您可以在客户端过滤它们 - 也就是说,查询比您需要的更大的文档页面,检查客户端上的消息属性正则表达式,扔掉你不需要的文件。

如果该方法存在太多误报,您可以使用Admin UI在为JSON属性存储的消息XML元素上创建字段索引。 (使用查询控制台浏览数据库并找出XML的命名空间。)在字段索引中,关闭词干,措辞,区分大小写和变音符号敏感的搜索。打开单词,尾随通配符和一个字符搜索。 (不要打开位置。)

重新编制索引后,在字段上执行单词查询,类似于:

String wordQueryOptions =
  {"punctuation-sensitive", "space-sensitive", "wildcarded"};
...
qb.and(
  qb.word(qb.field("yourMsgField"), FragmentScope.Documents,
    wordQueryOptions, "34=1"),
  qb.word(qb.field("yourMsgField"), FragmentScope.Documents,
    wordQueryOptions, "49=ABC*")
  )

最后,修改用于查询的查询选项,将“过滤”指定为搜索选项。

希望有帮助,

答案 1 :(得分:1)

如果您将文档存储在MarkLogic中的本机json xml表单中,这使它们看起来像这样:

<?xml  version="1.0" encoding="UTF-8"?>
<json type="object" xmlns="http://marklogic.com/xdmp/json/basic">
    <id type="number">233457657</id>
    <message type="string">8=FIX.4.3 9=118 335=A 34=1 49=ABCMKG</message>
</json>

您可以在QConsole中使用以下内容进行查询:

xquery version "1.0-ml";
import module namespace json = "http://marklogic.com/xdmp/json"
    at "/MarkLogic/json/json.xqy";

declare namespace jbasic = "http://marklogic.com/xdmp/json/basic";

cts:search(fn:doc(),cts:and-query((
    cts:element-word-query(xs:QName("jbasic:message"),"35=A","wildcarded"),
    cts:element-word-query(xs:QName("jbasic:message"),"49=ABC*","wildcarded")
  )))

在docs.marklogic.com的教程部分,您可以找到有关如何使用JAVA api执行此操作的示例。请检查此链接:https://developer.marklogic.com/learn/java/custom-search#search-using-an-element-word-constraint

HTH,

彼得