我正在使用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很新,并且对文档有点困惑。 谢谢!
答案 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,
彼得