我对marklogic不熟悉。我试图在java应用程序中使用marklogic nosql数据库执行简单的小于/大于查询。
java:v14标记逻辑:v9
假设我有一个“用户”数据库,示例文档如下所示:
{
"name": "some name",
"dateOfBirth": "1991-07-01",
...
...
}
我期望查询的sql版本是select*from user where dateofbirth>“1980-01-01”
在java中使用以下代码
StructuredQueryBuilder qb = new StructuredQueryBuilder();
StructuredQueryDefinition structuredQueryDefinition = qb.range(qb.pathIndex("/dateOfBirth"),
"xs:string",
(String[]) null,
StructuredQueryBuilder.Operator.GT,
eachCriteria.getValue());
markLogicTemplate.search(CombinedQueryDefinitionBuilder.combine(structuredQueryDefinition), User.class);
使用以下代码创建路径索引:
xquery version "1.0-ml";
import module namespace admin = "http://marklogic.com/xdmp/admin"
at "/MarkLogic/admin.xqy";
let $config := admin:get-configuration()
let $dbid := xdmp:database("user")
let $pathspec := admin:database-range-path-index(
$dbid,
"string",
"/dateOfBirth",
"http://marklogic.com/collation/",
fn:false(),
"ignore")
return
admin:database-add-range-path-index($config, $dbid, $pathspec)
java中的以下异常:
com.marklogic.client.FailedRequestException: Local message: search failed: Bad Request. Server Message: XDMP-PATHRIDXNOTFOUND: cts:search(fn:collection(), cts:and-query((cts:collection-query("User"), cts:path-range-query("/dateOfBirth", ">", "1980-01-01", ("collation=http://marklogic.com/collation/"), 1)), ()), ("unfiltered", cts:score-order("descending")), xs:double("0"), ()) -- No string path range index for /dateOfBirth collation=http://marklogic.com/collation/
创建索引后尝试重新运行marklogic服务器,但仍然没有成功。
提前谢谢你的帮助。
2条答案
按热度按时间23c0lvtd1#
上述范围索引和java实现存在一些基本问题:
“/dateofbirth”是w3c不兼容的xml/xpath。xml文档必须有根元素。JavaAPI不会返回任何xpath无效的结果。
我的示例文档:
/person1.xml
<person> <name>Alice Alice</name> <dob>1991-07-01</dob> </person>
/person2.xml
```Lewis Carroll
1981-07-01
StructuredQueryDefinition queryDef = sqb.range(sqb.pathIndex("/person/dob"), "xs:string", Operator.GT, "1980-01-01");
Query result:
<search:response snippet-format="snippet" total="2" start="1" page-length="10" xmlns:search="http://marklogic.com/appservices/search">
<search:result index="1" uri="/person1.xml" path="fn:doc("/person1.xml")" score="0" confidence="0" fitness="0" href="/v1/documents?uri=%2Fperson1.xml" mimetype="application/xml" format="xml">
search:snippet
<search:match path="fn:doc("/person1.xml")/person/dob">search:highlight1991-07-01</search:highlight></search:match>
</search:snippet>
</search:result>
<search:result index="2" uri="/person2.xml" path="fn:doc("/person2.xml")" score="0" confidence="0" fitness="0" href="/v1/documents?uri=%2Fperson2.xml" mimetype="application/xml" format="xml">
search:snippet
<search:match path="fn:doc("/person2.xml")/person/dob">search:highlight1981-07-01</search:highlight></search:match>
</search:snippet>
</search:result>
...............
</search:response>
Session completed: 2020-09-07T15:49:26.409488
StructuredQueryDefinition queryDef = sqb.range(sqb.pathIndex("/person/dob"), "xs:date", Operator.GT, "1980-01-01");
xv8emn3q2#
要在查询中使用范围索引,范围索引和查询必须指定
相同的数据类型
字符串数据类型的排序规则相同
我猜这个范围索引和查询的数据类型应该是date(因此,即使字符串较小,也匹配较大的日期)。json文档中的字符串值可以作为日期值(以及其他许多数据类型)进行索引。
根据您的需求,您可以考虑使用tde对文档进行索引,并将行投影到文档之外。在javaapi中,可以使用rowmanager来检索行。请参见:
https://docs.marklogic.com/guide/app-dev/tde
https://docs.marklogic.com/guide/java/opticjava
希望有帮助,