今天在使用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>
再试了一下,我的乖乖,问题解决了。不过仅管问题已经解决,但其中的子丑寅卯还是没弄明白 。