今天在使用Solr的DataImportHandler时,需要用一个JavaScript函数来对数据做预处理,写的JS代码如下:
<script> <![CDATA[ var reg = new RegExp("[^\\d,]|^,+|,+$","g"); function cleanFJID(row){ var val = row.get("FJ"); var val = val.replace(reg,""); //把无效字符去掉 if(val=="") val = "null"; row.put('FJ', val); return row; } ]]> </script>
这段代码如果在浏览器里执行,应该是没有问题的,但是DIH执行时却报错:
警告: transformer threw error
org.apache.solr.handler.dataimport.DataImportHandlerException: Could not invoke method :cleanFJID
<script>
null</script> Processing Document # 1
at org.apache.solr.handler.dataimport.ScriptTransformer.transformRow(ScriptTransformer.java:58)
at org.apache.solr.handler.dataimport.EntityProcessorWrapper.applyTransformer(EntityProcessorWrapper.java:195)
at org.apache.solr.handler.dataimport.EntityProcessorWrapper.nextRow(EntityProcessorWrapper.java:241)
at org.apache.solr.handler.dataimport.DocBuilder.buildDocument(DocBuilder.java:357)
at org.apache.solr.handler.dataimport.DocBuilder.doFullDump(DocBuilder.java:242)
at org.apache.solr.handler.dataimport.DocBuilder.execute(DocBuilder.java:180)
at org.apache.solr.handler.dataimport.DataImporter.doFullImport(DataImporter.java:331)
at org.apache.solr.handler.dataimport.DataImporter.runCmd(DataImporter.java:389)
at org.apache.solr.handler.dataimport.DataImporter$1.run(DataImporter.java:370)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.solr.handler.dataimport.ScriptTransformer.transformRow(ScriptTransformer.java:53)
... 8 more
Caused by: javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: The choice of Java constructor replace matching JavaScript argument types (function,string) is ambiguous; candidate constructors are:
class java.lang.String replace(char,char)
class java.lang.String replace(java.lang.CharSequence,java.lang.CharSequence) (<Unknown source>#6) in <Unknown source> at line number 6
at com.sun.script.javascript.RhinoScriptEngine.invoke(RhinoScriptEngine.java:184)
at com.sun.script.javascript.RhinoScriptEngine.invokeFunction(RhinoScriptEngine.java:142)
... 13 more
2010-6-18 1:43:40 org.apache.solr.handler.dataimport.DocBuilder buildDocument
严重: Exception while processing: XZ_SJFW document : SolrInputDocument[{}]
看字面的意思是JS的replace函数与java的replace方法混淆,导致javascript引擎不知该调用哪个方法,所以,我就使用了另外一种方法来引用正则表达式,修改后JS如下:
<script> <![CDATA[ //var reg = new RegExp("[^\\d,]|^,+|,+$","g"); function cleanFJID(row){ var val = row.get("FJ"); var val = val.replace(/[^\\d,]|^,+|,+$/g,""); //把无效字符去掉 if(val=="") val = "null"; row.put('FJ', val); return row; } ]]> </script>
满以为这样修改就不会再有问题,可以一执行,还是报差不多的错:
警告: transformer threw error
org.apache.solr.handler.dataimport.DataImportHandlerException: Could not invoke method :cleanFJID
<script>
null</script> Processing Document # 1
at org.apache.solr.handler.dataimport.ScriptTransformer.transformRow(ScriptTransformer.java:58)
at org.apache.solr.handler.dataimport.EntityProcessorWrapper.applyTransformer(EntityProcessorWrapper.java:195)
at org.apache.solr.handler.dataimport.EntityProcessorWrapper.nextRow(EntityProcessorWrapper.java:241)
at org.apache.solr.handler.dataimport.DocBuilder.buildDocument(DocBuilder.java:357)
at org.apache.solr.handler.dataimport.DocBuilder.doFullDump(DocBuilder.java:242)
at org.apache.solr.handler.dataimport.DocBuilder.execute(DocBuilder.java:180)
at org.apache.solr.handler.dataimport.DataImporter.doFullImport(DataImporter.java:331)
at org.apache.solr.handler.dataimport.DataImporter.runCmd(DataImporter.java:389)
at org.apache.solr.handler.dataimport.DataImporter$1.run(DataImporter.java:370)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.solr.handler.dataimport.ScriptTransformer.transformRow(ScriptTransformer.java:53)
... 8 more
Caused by: javax.script.ScriptException: sun.org.mozilla.javascript.internal.EvaluatorException: The choice of Java constructor replace matching JavaScript argument types (function,string) is ambiguous; candidate constructors are:
class java.lang.String replace(char,char)
class java.lang.String replace(java.lang.CharSequence,java.lang.CharSequence) (<Unknown source>#5) in <Unknown source> at line number 5
at com.sun.script.javascript.RhinoScriptEngine.invoke(RhinoScriptEngine.java:184)
at com.sun.script.javascript.RhinoScriptEngine.invokeFunction(RhinoScriptEngine.java:142)
... 13 more
2010-6-18 1:46:50 org.apache.solr.handler.dataimport.DocBuilder buildDocument
严重: Exception while processing: XZ_SJFW document : SolrInputDocument[{}]
这下我可傻眼了,搞不懂是什么原因了 !
上网一顿狠找,找到洋鬼子的一个贴子:
http://www.mirthcorp.com/community/forums/showthread.php?t=235
英文水平差,意思没看明白,但看到5楼有人回复,建议把字符串改成
var input = new String(strOut);
再调用replace试试,我照猫画虎,也把代码改成这样:
<script> <![CDATA[ //var reg = new RegExp("[^\\d,]|^,+|,+$","g"); function cleanFJID(row){ var val = row.get("FJ"); var str = new String(val); var val = str.replace(/[^\d,]|^,+|,+$/g,""); //把无效字符去掉 // var val = val.replace(reg,""); //把无效字符去掉 if(val=="") val = "null"; row.put('FJ', val); return row; } ]]> </script>
再试了一下,我的乖乖,问题解决了。不过仅管问题已经解决,但其中的子丑寅卯还是没弄明白 。