2017-07-25 7 views
12

जब MongoDB से एक डेटा आयात कर, Solr निम्न त्रुटि फेंकता है:org.apache.solr.common.SolrException: TransactionLog क्लास org.bson.types.ObjectId को क्रमबद्ध करने के बारे में नहीं जानता है; ऑब्जेक्ट रिसेल्वर को लागू करने का प्रयास करें?

org.apache.solr.common.SolrException: TransactionLog doesn't know how to serialize class org.bson.types.ObjectId; try implementing ObjectResolver? 
at org.apache.solr.update.TransactionLog$1.resolve(TransactionLog.java:100) 
at org.apache.solr.common.util.JavaBinCodec.writeVal(JavaBinCodec.java:234) 
at org.apache.solr.common.util.JavaBinCodec.writeSolrInputDocument(JavaBinCodec.java:589) 
at org.apache.solr.update.TransactionLog.write(TransactionLog.java:395) 
at org.apache.solr.update.UpdateLog.add(UpdateLog.java:532) 
at org.apache.solr.update.UpdateLog.add(UpdateLog.java:516) 
at org.apache.solr.update.DirectUpdateHandler2.doNormalUpdate(DirectUpdateHandler2.java:320) 
at org.apache.solr.update.DirectUpdateHandler2.addDoc0(DirectUpdateHandler2.java:239) 
at org.apache.solr.update.DirectUpdateHandler2.addDoc(DirectUpdateHandler2.java:194) 
at org.apache.solr.update.processor.RunUpdateProcessor.processAdd(RunUpdateProcessorFactory.java:67) 
at org.apache.solr.update.processor.UpdateRequestProcessor.processAdd(UpdateRequestProcessor.java:55) 
at org.apache.solr.update.processor.DistributedUpdateProcessor.doLocalAdd(DistributedUpdateProcessor.java:979) 
at org.apache.solr.update.processor.DistributedUpdateProcessor.versionAdd(DistributedUpdateProcessor.java:1192) 
at org.apache.solr.update.processor.DistributedUpdateProcessor.processAdd(DistributedUpdateProcessor.java:748) 
at org.apache.solr.update.processor.LogUpdateProcessorFactory$LogUpdateProcessor.processAdd(LogUpdateProcessorFactory.java:103) 
at org.apache.solr.handler.dataimport.SolrWriter.upload(SolrWriter.java:80) 
at org.apache.solr.handler.dataimport.DataImportHandler$1.upload(DataImportHandler.java:254) 
at org.apache.solr.handler.dataimport.DocBuilder.buildDocument(DocBuilder.java:526) 
at org.apache.solr.handler.dataimport.DocBuilder.buildDocument(DocBuilder.java:414) 
at org.apache.solr.handler.dataimport.DocBuilder.doFullDump(DocBuilder.java:329) 
at org.apache.solr.handler.dataimport.DocBuilder.execute(DocBuilder.java:232) 
at org.apache.solr.handler.dataimport.DataImporter.doFullImport(DataImporter.java:415) 
at org.apache.solr.handler.dataimport.DataImporter.runCmd(DataImporter.java:474) 
at org.apache.solr.handler.dataimport.DataImporter.lambda$runAsync$0(DataImporter.java:457) 
at java.lang.Thread.run(Thread.java:748) 

मेरे Solr संस्करण 6.6.0 है। त्रुटि का कारण क्या हो सकता है और इसे कैसे हल किया जा सकता है?

उत्तर

1

त्रुटि संदेश के अनुसार,

आप org.bson.types.ObjectId प्रकार के लिए JavaBinCodec.ObjectResolver लागू करने के लिए इतना Solr इस वर्ग के उदाहरणों को क्रमानुसार करने के लिए कैसे पता चल जाएगा की जरूरत है।

JavaBinCodec.ObjectResolver Documentation

public static interface JavaBinCodec.ObjectResolver Allows extension of JavaBinCodec to support serialization of arbitrary data types. Implementors of this interface write a method to serialize a given object using an existing JavaBinCodec

बार जब आप अपने JavaBinCodec.ObjectResolver कार्यान्वयन बारे में आप इसे JavaBinCodec

JavaBinCodec Documentation

public class JavaBinCodec extends Object Defines a space-efficient serialization/deserialization format for transferring data. JavaBinCodec has built in support many commonly used types. This includes primitive types (boolean, byte, short, double, int, long, float), common Java containers/utilities (Date, Map, Collection, Iterator, String, Object[], byte[]), and frequently used Solr types (NamedList, SolrDocument, SolrDocumentList). Each of the above types has a pair of associated methods which read and write that type to a stream.

Classes that aren't supported natively can still be serialized/deserialized by providing an JavaBinCodec.ObjectResolver object that knows how to work with the unsupported class. This allows JavaBinCodec to be used to marshall/unmarshall arbitrary content.

NOTE -- JavaBinCodec instances cannot be reused for more than one marshall or unmarshall operation.

+0

ओपी मोंगो कनेक्टर का उपयोग कर रहा है जिसका उपयोग बिना किसी अतिरिक्त कार्यान्वयन के मोंगोडब से डेटा आयात के लिए व्यापक रूप से किया जाता है। – Rajesh

2

का उपयोग कर रजिस्टर चाहिए मैं की कोशिश करते हुए इस मुद्दे में आए महत्वपूर्ण mongoDB में एकाधिक संग्रह से टी डेटा।

मान लीजिए कि आप मोंगो-कनेक्टर का उपयोग नहीं कर रहे हैं, मैंने डेटा आयात करने के लिए निम्नलिखित का उपयोग किया था।

लौटे '_ id' के बाद से प्रकार ObjectId की है, मेरे समाधान के आसपास काम '_id' को स्ट्रिंग में अनुक्रमणित करने से पहले स्ट्रिंग में कनवर्ट करना था और '_id' के संबंध में पूछताछ करते समय, क्वेरी चलाने से पहले ऑब्जेक्टआईडी टाइप करने के लिए इसे परिवर्तित करना था।

solr mongo आयातक डाउनलोड करें और निम्न परिवर्तन करें। इन परिवर्तनों के बाद

@Override 
public Iterator<Map<String, Object>> getData(String query) { 

    DBObject queryObject = new BasicDBObject(); 

    /* If querying by _id, since the id is a string now, 
    * it has to be converted back to type ObjectId() using the 
    * constructor 
    */ 
    if(query.contains("_id")){ 
     @SuppressWarnings("unchecked") 
     Map<String, String> queryWithId = (Map<String, String>) JSON.parse(query); 
     String id = queryWithId.get("_id"); 
     queryObject = new BasicDBObject("_id", new ObjectId(id)); 
    } 
    else{ 
     queryObject = (DBObject) JSON.parse(query); 
    } 

    LOG.debug("Executing MongoQuery: " + query.toString()); 

    long start = System.currentTimeMillis(); 
    mongoCursor = this.mongoCollection.find(queryObject); 
    LOG.trace("Time taken for mongo :" 
      + (System.currentTimeMillis() - start)); 

    ResultSetIterator resultSet = new ResultSetIterator(mongoCursor); 
    return resultSet.getIterator(); 
} 

आप उपयोग कर जार का निर्माण कर सकते हैं:

MongoMapperTransformer.java

public class MongoMapperTransformer extends Transformer { 

@Override 
public Object transformRow(Map<String, Object> row, Context context) { 

    for (Map<String, String> map : context.getAllEntityFields()) { 
     String mongoFieldName = map.get(MONGO_FIELD); 
     String mongoId = map.get(MONGO_ID); 
     if (mongoFieldName == null) 
      continue; 

     String columnFieldName = map.get(DataImporter.COLUMN); 

     //If the field is ObjectId convert it into String 
     if (mongoId != null && Boolean.parseBoolean(mongoId)) { 
      Object srcId = row.get(columnFieldName); 
      row.put(columnFieldName, srcId.toString()); 
     } 
     else{ 
      row.put(columnFieldName, row.get(mongoFieldName)); 
     } 
    } 

    return row; 
} 


public static final String MONGO_FIELD = "mongoField"; 

//To identify the _id field 
public static final String MONGO_ID = "objectIdToString"; 

} 

इसके बाद, निम्नलिखित के साथ MongoDataSource.java में समारोह

public Iterator <Map<String, Object>> getData(String query){...} 

बदलें चींटी।

lib निर्देशिका में जार (सोलर मोंगो आयातक और मोंगो-जावा-ड्राइवर) की प्रतिलिपि बनाएँ। मैंने उन्हें $ {solr-install-dir}/contrib/dataimport-handler/lib

सॉल-कॉन्फ़िगरेशन में lib निर्देश जोड़ें।ऊपर जार के लिए xml:

<lib dir="${solr.install.dir:../../../..}/contrib/dataimporthandler/lib" regex=".*\.jar" /> 

अंत में, यहाँ मोंगो संग्रह और डेटा-config.xml

User collection 
{ 
    "_id" : ObjectId("56e9c892e4b0355017b2fa0f"), 
    "name" : "User1", 
    "phone" : "123456789" 
} 

Address collection 
{ 
    "_id" : ObjectId("56e9c892e4b0355017b2fa0f"), 
    "address" : "#666, Maiden street" 
} 

डेटा-config.xml का एक उदाहरण है

मत भूलना उल्लेख करने के लिए objectIdToString = _id फ़ील्ड के लिए "सत्य" ताकि MongoMapperTransformer आईडी को स्ट्रिंग कर सके।

<dataConfig> 
    <dataSource name="MyMongo" 
      type="MongoDataSource" 
      database="test" 
      /> 
    <document name="UserDetails"> 
    <!-- if query="" then it imports everything --> 
     <entity name="users" 
      processor="MongoEntityProcessor" 
      query="" 
      collection="user" 
      datasource="MyMongo" 
      transformer="MongoMapperTransformer"> 
       <field column="_id" name="id" mongoField="_id" objectIdToString="true" /> 
       <field column="phone" name="phone" mongoField="phone"/> 

      <entity name="address" 
       processor="MongoEntityProcessor" 
       query="{_id:'${users._id}'}" 
       collection="address" 
       datasource="MyMongo" 
       transformer="MongoMapperTransformer"> 
       <field column="address" name="adress" mongoField="address"/> 
      </entity> 
    </entity> 
    </document> 
</dataConfig> 

प्रबंधित-स्कीमा में आईडी फ़ील्ड स्ट्रिंग के रूप में होगा। इसके अलावा, यदि आपके पास मोंगोडब में नेस्टेड ऑब्जेक्ट्स हैं तो आपको स्क्रिप्ट ट्रांसफॉर्मर्स का उपयोग सोलर में इंडेक्स करने के लिए करना होगा।

उम्मीद है कि यह मदद करता है, शुभकामनाएँ!

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

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