2016-03-01 11 views
8

मेरे पास कुछ कोड है जो “invalid values” setting on an element range index का उपयोग करता है। इस मामले में, मैंने अपने डेटाबेस में onDate तत्व पर dateTime तत्व श्रेणी अनुक्रमणिका कॉन्फ़िगर की है (जो एक्सएमएल तत्वों और JSON गुणों दोनों पर लागू होगी)। मैंने उस इंडेक्स को अमान्य मानों को अस्वीकार करने के लिए सेट कर दिया है। इस सेटिंग का अर्थ है कि यदि मैं onDate तत्व का मान सेट करने का प्रयास करता हूं और यह dateTime पर जा सकता है या शून्य (जेएसओएन मेंया XML में xsi:nil="true") है, तो मेरा अपडेट विफल हो जाएगा। (विपरीत व्यवहार पूरी तरह से अमान्य मान अनदेखी करने के लिए है।)मैं मार्कलॉगिक अनुरोध में कुछ अपवाद क्यों नहीं पकड़ सकता?

मैं MarkLogic 8.0-4 में सर्वर-साइड JavaScript में निम्न कोड की कोशिश की:

'use strict'; 
declareUpdate(); 
var errors = []; 
var inputs = { 
'/37107-valid.json': (new Date()).toISOString(), 
'/37107-invalid.json': 'asdf', // Should throw an error 
'/37107-null.json': null 
}; 

for(var uri in inputs) { 
try { 
    xdmp.documentInsert(
    uri, 
    { 'onDate': inputs[uri] }, 
    xdmp.defaultPermissions(), 
    ['37107'] // Collections 
    ); 
} catch(err) { 
    errors.push(err); 
} 
} 
errors.length; 

मैं अपेक्षा की होगी मेरे अनुरोध सफल होने के लिए और समाप्त करने के लिए 1 === errors.length के साथ, क्योंकि केवल दूसरा डालने में असफल रहा होगा क्योंकि 'asdf'dateTime के रूप में जाति योग्य नहीं है और यह शून्य नहीं है। हालांकि, इसके बजाय मुझे XDMP-RANGEINDEX त्रुटि मिलती है और मेरा लेनदेन विफल रहता है। मेरा try/catch क्यों काम नहीं करता है?

उत्तर

13

समस्या यह है कि MarkLogic प्रक्रियाओं को लेनदेन अपडेट कैसे करता है। प्रत्येक xdmp.docuentInsert(…) कॉल के साथ डेटा को वास्तव में बदलने के बजाय, मार्कलॉगिक सभी अपडेट्स को कतारबद्ध करता है और अनुरोध के अंत में उन्हें परमाणु रूप से लागू करता है। (यही कारण है कि आप एक ही लेनदेन के भीतर डेटाबेस अपडेट नहीं देख सकते हैं।) इस प्रकार, लूप को निष्पादित करने के बाद त्रुटि को फेंक नहीं दिया जा रहा है और डेटाबेस कतारबद्ध लेनदेन करने की कोशिश करता है। यह व्यवहार XQuery (थोड़ा सरलीकृत) में एक ही है:

let $uris := (
'/37107-valid.xml', 
'/37107-invalid.xml', 
'/37107-null.xml' 
) 
let $docs := (
<onDate>{fn:current-dateTime()}</onDate>, 
<onDate>asdf</onDate>, 
<onDate xsi:nil="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/> 
) 
return 
for $uri at $i in $uris 
return 
    try { 
    xdmp:document-insert($uri, $docs[$i],(), ('37107')) 
    } catch($err) { 
    xdmp:log($err) 
    } 

क्रम त्रुटियों तुल्यकालिक पकड़ने के लिए, आप अपने स्वयं के लेन-देन में प्रत्येक अद्यतन लगाने की जरूरत होगी। आम तौर पर, यह दृष्टिकोण मार्कलोगिक के डिफ़ॉल्ट लेनदेन हैंडलिंग की तुलना में बहुत धीमा और संसाधन गहन होगा। हालांकि, यह कवर करने के लिए क्या हो रहा है यह दिखाने के लिए यहां चित्रकारी है और इस तरह के विशिष्ट उपयोग मामलों के लिए काम में आ सकता है।

नीचे दिए गए उदाहरण में, मैं पैरेंट अनुरोध से अलग लेनदेन में एक फ़ंक्शन को "कॉल" करने के लिए xdmp.invokeFunction() का उपयोग करता हूं। (जीत के लिए प्रथम श्रेणी के कार्यों!) यह अद्यतनों को पूरी तरह से लागू करने की अनुमति देता है (या एक त्रुटि के साथ वापस लुढ़काया जाता है) और कॉलिंग मॉड्यूल अद्यतन (या त्रुटियों) को देखने के लिए अनुमति देता है। मैंने अपने applyAs() फ़ंक्शन में निम्न-स्तर xdmp.invokeFunction() को कुछ niceties प्रदान करने के लिए लपेट लिया है, जैसे कि करीबी फ़ंक्शन पर फ़ंक्शन तर्कों को सही ढंग से पास करना।

'use strict'; 

var errors = []; 
var inputs = { 
'/37107-valid.json': (new Date()).toISOString(), 
'/37107-invalid.json': 'asdf', 
'/37107-null.json': null 
}; 

var insert = applyAs(
function(uri, value) { 
    return xdmp.documentInsert(
    uri, 
    { 'onDate': inputs[uri] }, 
    xdmp.defaultPermissions(), 
    ['37107'] 
    ); 
}, 
{ isolation: 'different-transaction', transactionMode: 'update' }, 
'one' 
); 

for(var uri in inputs) { 
try { 
    insert(uri, inputs[uri]); 
} catch(err) { 
    errors.push(err); 
} 
} 
errors.length; // Correctly returns 1 


// <https://gist.github.com/jmakeig/0a331823ad9a458167f6> 
function applyAs(fct, options, returnType /* 'many', 'one', 'iterable' (default) */) { 
    options = options || {}; 
    return function() { 
    var params = Array.prototype.slice.call(arguments); 
    // Curry the function to include the params by closure. 
    // xdmp.invokeFunction requires that invoked functions have 
    // an arity of zero. 
    var f = (function() { 
     return fct.apply(null, params); 
    }).bind(this); 
    // Allow passing in user name, rather than id 
    if(options.user) { options.userId = xdmp.user(options.user); delete options.user; } 
    // Allow the functions themselves to declare their transaction mode 
    if(fct.transactionMode && !(options.transactionMode)) { options.transactionMode = fct.transactionMode; } 
    var result = xdmp.invokeFunction(f, options); // xdmp.invokeFunction returns a ValueIterator 
    switch(returnType) { 
     case 'one': 
     // return fn.head(result); // 8.0-5 
     return result.next().value; 
     case 'many': 
     return result.toArray(); 
     case 'iterable': 
     default: 
     return result; 
    } 
    } 
} 
+0

अब आप अपने जवाब को स्वीकार करने की जरूरत है;) – joemfb

+0

मैं मतपत्र भरने से बचने के लिए कल्पना, आप दो दिनों के लिए अपने स्वयं के जवाब स्वीकार नहीं कर सकते। –

संबंधित मुद्दे