MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

मोंगोडीबी बीएसओएन कोडेक ऑब्जेक्ट एन्कोडिंग करते समय उपयोग नहीं किया जा रहा है

कई दिनों के शोध के बाद, मैंने एक समाधान निकाला है।

DutyBlockCodec LocalDateCodec . पर निर्भर करता है (जो मैंने बनाया) एन्कोड/डीकोड करने के लिए। यह निर्भरता केवल दो कोडेक को एक ही कोडेक रजिस्ट्री में जोड़ने से संतुष्ट नहीं होती है। समाधान एक CodecRegistry . पास करना है कोडेक्स युक्त ऑब्जेक्ट जो DutyBlockCodec निर्भर करता है (उदाहरण के लिए एक CodecRegistry इसके भीतर LocalDateCodec . है ) से DutyBlockCodec का कंस्ट्रक्टर, जिसे एक सदस्य चर के रूप में संग्रहीत किया जाता है। LocalDateCodec . का उपयोग करने के लिए एन्कोड करने के लिए, मैं EncoderContext.encodeWithChildContext() . का उपयोग करता हूं विधि, कोडेक, लेखक, और एनकोड करने के लिए तत्व में गुजर रहा है। इसके अतिरिक्त, मैं Document लिखने के बजाय अलग-अलग फ़ील्ड लिखता हूं String के रूप में (जैसा कि मेरे मूल कोड में है)। इस प्रकार DutyBlock कोडेक इस तरह दिखता है:

public class DutyBlockCodec implements Codec<DutyBlock> {
    private final CodecRegistry codecRegistry;

    public DutyBlockCodec(final CodecRegistry codecRegistry) {
        this.codecRegistry = codecRegistry;
    }

    @Override
    public void encode(BsonWriter writer, DutyBlock t, EncoderContext ec) {
        writer.writeStartDocument();
            Codec dateCodec = codecRegistry.get(LocalDate.class);
            writer.writeName("startDate");
            ec.encodeWithChildContext(dateCodec, writer, t.getStartDate());
            writer.writeName("endDate");
            ec.encodeWithChildContext(dateCodec, writer, t.getEndDate());
            writer.writeName("blockLength");
            writer.writeInt32(t.getBlockLength());
            writer.writeName("pointValue");
            writer.writeDouble(t.getPointValue());

            //Writing ArrayList of RAs
            writer.writeName("assigned");
            writer.writeStartArray();
                for (Ra ra : t.getRasOnDuty()) {
                    Codec raCodec = codecRegistry.get(Ra.class);
                    ec.encodeWithChildContext(raCodec, writer, ra);
                }
            writer.writeEndArray();
        writer.writeEndDocument();
    }

    @Override
    public Class<DutyBlock> getEncoderClass() {
        return DutyBlock.class;
    }

    @Override
    public DutyBlock decode(BsonReader reader, DecoderContext dc) {
        reader.readStartDocument();
            Codec<LocalDate> dateCodec = codecRegistry.get(LocalDate.class);
            reader.readName();
            LocalDate startDate = dateCodec.decode(reader, dc);
            reader.readName();
            LocalDate endDate = dateCodec.decode(reader, dc);
            reader.readName();
            int blockLength = reader.readInt32();
            reader.readName();
            double pointValue = reader.readDouble();

            //Reading ArrayList of RAs
            reader.readName();
            Codec<Ra> raCodec = codecRegistry.get(Ra.class);
            ArrayList<Ra> rasOnDuty = new ArrayList<>();
            reader.readStartArray();
                while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
                    rasOnDuty.add(raCodec.decode(reader, dc));
                }
            reader.readEndArray();
        reader.readEndDocument();

        return new DutyBlock(startDate, endDate, blockLength, pointValue, rasOnDuty);
    }

}

DutyBlockCodec दूसरे कोडेक पर निर्भर करता है, और इसलिए एक CodecRegistry . की आवश्यकता होती है इसके निर्माता पर पारित किया जाना है। जबकि मेरा मानना ​​है कि CodecRegistry . बनाना संभव है LocalDateCodec . के साथ , फिर इसे DutyBlockCodec . के तर्क के रूप में पास करें कंस्ट्रक्टर, फिर एक और CodecRegistry create बनाएं दोनों LocalDateCodec . युक्त और DutyBlockCodec , यह बल्कि भ्रमित करने वाला है, और MongoDB एक कार्यक्षमता प्रदान करता है, CodecProvider इस प्रक्रिया को सुविधाजनक बनाने के लिए।

CodecProvider का उपयोग करना इंटरफ़ेस, मैंने एक DutyBlockCodecProvider लिखा था

public class DutyBlockCodecProvider implements CodecProvider {
    @Override
    public <T> Codec<T> get(Class<T> type, CodecRegistry cr) {
        if (type == DutyBlock.class) {
            return (Codec<T>) new DutyBlockCodec(cr);
        }
        return null;
    }
}

मैंने ये CodecProviders जोड़े हैं MongoDB क्लाइंट के लिए CodecRegistries.fromProviders() . का उपयोग कर विधि।

CodecRegistry codecRegistry = CodecRegistries.fromRegistries(
            CodecRegistries.fromCodecs(new LocalDateCodec()),
            CodecRegistries.fromProviders(
                    new RaCodecProvider(),
                    new DutyBlockCodecProvider(),
                    new ScheduledDutyCodecProvider()),
            MongoClient.getDefaultCodecRegistry());  
    MongoClientOptions options = MongoClientOptions.builder()
            .codecRegistry(codecRegistry).build();
    mongoClient = new MongoClient(new ServerAddress(), options);
    db = mongoClient.getDatabase("DutySchedulerDB");

इस परियोजना के लिए मेरा स्रोत कोड https://github.com/desrepair/DutyScheduler पर पाया जा सकता है, मैं लोगों के किसी भी प्रश्न का उत्तर देने के लिए तैयार हूं।



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. ssh . के माध्यम से MongoDB सिंक करें

  2. Cosmos MongoDB एकीकरण के साथ Azure फ़ंक्शन सहेज नहीं रहा है

  3. Mongo में सभी दस्तावेज़ों में स्ट्रिंग को कैसे बदलें?

  4. ClusterControl सलाहकारों के साथ MongoDB की निगरानी और सुरक्षा

  5. मोंगो डीबी में सेव और इंसर्ट में क्या अंतर है?