对于我们存储在 MarkLogic 中的每个 XML,我们将计算值存储在文档的关联属性中。这些值之一是可能很大的十进制值。这导致了异常,因为 Marklogic Java API 正在以 MarkLogic 服务器不喜欢的方式格式化它发送到 MarkLogic 服务器的 XML 中的数字。
我们在存储在属性中的“TotalObligatedAmount”元素上设置了范围元素索引:
下面的 Java 代码重现了我们看到的问题:
import java.nio.charset.StandardCharsets;
import org.apache.commons.io.IOUtils;
import org.w3c.dom.Document;
import com.marklogic.client.DatabaseClient;
import com.marklogic.client.document.XMLDocumentManager;
import com.marklogic.client.io.DOMHandle;
import com.marklogic.client.io.DocumentMetadataHandle;
@Component
public class LoadTester {
private final XMLDocumentManager mgr;
public LoadTester(DatabaseClient client) {
this.mgr = client.newXMLDocumentManager();
}
public void loadTest() throws Exception {
String uri = "testDocument.xml";
DOMHandle handle = new DOMHandle();
String xml = "<test><value>Hello World</value></test>";
Document doc = handle.getFactory().newDocumentBuilder()
.parse(IOUtils.toInputStream(xml, StandardCharsets.UTF_8));
DocumentMetadataHandle metadataHandle = new DocumentMetadataHandle();
metadataHandle.withProperty("TotalObligatedAmount",Double.valueOf(18912626.00));
handle.set(doc);
mgr.write(mgr.newDescriptor(uri), metadataHandle, handle);
}
}
这会导致以下异常:
Exception in thread "main" com.marklogic.client.FailedRequestException: Local message: write failed: Bad Request. Server Message: XDMP-RANGEINDEX: Range index error: decimal xdmp:document-properties("testDocument.xml")/prop:properties/TotalObligatedAmount: XDMP-LEXVAL: Invalid lexical value "1.8912626E7"
at com.marklogic.client.impl.OkHttpServices.putPostDocumentImpl(OkHttpServices.java:1697)
at com.marklogic.client.impl.OkHttpServices.putDocument(OkHttpServices.java:1344)
at com.marklogic.client.impl.DocumentManagerImpl.write(DocumentManagerImpl.java:940)
at com.marklogic.client.impl.DocumentManagerImpl.write(DocumentManagerImpl.java:888)
at com.marklogic.client.impl.DocumentManagerImpl.write(DocumentManagerImpl.java:827)
Java API 正在生成并发送到服务器的属性数据 XML 是:
<?xml version='1.0' encoding='utf-8'?>
<rapi:metadata xmlns:rapi="http://marklogic.com/rest-api"
xmlns:prop="http://marklogic.com/xdmp/property"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<prop:properties>
<TotalObligatedAmount xsi:type="xs:double">1.8912626E7</TotalObligatedAmount>
</prop:properties>
</rapi:metadata>
将属性序列化为 XML 时,十进制值 18,912,626.00 被转换为字符串 1.8912626E7,MarkLogic 服务器拒绝该字符串。
我能够单步执行代码以了解如何将双精度转换为字符串。com.marklogic.client.impl.ValueConverter
进行转换并使用方法将javax.xml.bind.DatatypeConverter.printDouble()
Double 转换为“1.8912626E7”字符串(最终使用 String.valueOf(doubleValue) 方法。
有谁知道我该如何解决这个问题?我需要在服务器上进行更改或配置 Java API 的方法吗?
我使用的是 5.2.0 版的 Java API 和 10.0-8.1 版的 MarkLogic 服务器。