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

जावा का उपयोग करके JSON फ़ाइल से MongoDB में डेटा आयात करें

1. परिचय

इस ट्यूटोरियल में, हम सीखेंगे कि कैसे फाइलों से JSON डेटा को पढ़ा जाए और स्प्रिंग बूट का उपयोग करके उन्हें MongoDB में आयात किया जाए। यह कई कारणों से उपयोगी हो सकता है:डेटा को पुनर्स्थापित करना, नए डेटा को बल्क में सम्मिलित करना, या डिफ़ॉल्ट मान सम्मिलित करना। MongoDB अपने दस्तावेज़ों की संरचना के लिए आंतरिक रूप से JSON का उपयोग करता है, इसलिए स्वाभाविक रूप से, हम आयात योग्य फ़ाइलों को संग्रहीत करने के लिए इसका उपयोग करेंगे। सादा पाठ होने के कारण, इस रणनीति में आसानी से संकुचित होने का लाभ भी है।

इसके अलावा, हम सीखेंगे कि आवश्यकता पड़ने पर हमारे कस्टम प्रकारों के विरुद्ध हमारी इनपुट फ़ाइलों को कैसे सत्यापित किया जाए। आखिरकार, हम एक API प्रदर्शित करेंगे ताकि हम इसे अपने वेब ऐप में रनटाइम के दौरान उपयोग कर सकें।

2. निर्भरता

आइए इन स्प्रिंग बूट निर्भरता को हमारे pom.xml . में जोड़ें :

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

हमें MongoDB के एक रनिंग इंस्टेंस की भी आवश्यकता होगी, जिसके लिए उचित रूप से कॉन्फ़िगर किए गए application.properties की आवश्यकता होती है। फ़ाइल।

3. JSON स्ट्रिंग्स आयात करना

JSON को MongoDB में आयात करने का सबसे सरल तरीका यह है कि इसे "org.bson.Document में परिवर्तित किया जाए। ” पहले आपत्ति करें। यह वर्ग बिना किसी विशिष्ट प्रकार के एक सामान्य MongoDB दस्तावेज़ का प्रतिनिधित्व करता है। इसलिए हमें उन सभी प्रकार की वस्तुओं के लिए रिपॉजिटरी बनाने के बारे में चिंता करने की ज़रूरत नहीं है जिन्हें हम आयात कर सकते हैं।

हमारी रणनीति JSON (एक फ़ाइल, संसाधन या स्ट्रिंग से) लेती है, इसे दस्तावेज़ . में बदल देती है s, और MongoTemplate . का उपयोग करके उन्हें सहेजता है . बैच संचालन आमतौर पर बेहतर प्रदर्शन करते हैं क्योंकि प्रत्येक ऑब्जेक्ट को अलग-अलग सम्मिलित करने की तुलना में राउंड ट्रिप की मात्रा कम हो जाती है।

सबसे महत्वपूर्ण बात, हम अपने इनपुट पर विचार करेंगे कि प्रति पंक्ति विराम में केवल एक JSON ऑब्जेक्ट है। इस तरह, हम आसानी से अपनी वस्तुओं का परिसीमन कर सकते हैं। हम इन कार्यात्मकताओं को दो वर्गों में समाहित करेंगे जिन्हें हम बनाएंगे:ImportUtils और ImportJsonService . आइए हमारे सेवा वर्ग से शुरू करें:

@Service
public class ImportJsonService {

    @Autowired
    private MongoTemplate mongo;
}

इसके बाद, चलिए एक विधि जोड़ते हैं जो JSON की पंक्तियों को दस्तावेज़ों में पार्स करती है:

private List<Document> generateMongoDocs(List<String> lines) {
    List<Document> docs = new ArrayList<>();
    for (String json : lines) {
        docs.add(Document.parse(json));
    }
    return docs;
}

फिर हम एक विधि जोड़ते हैं जो दस्तावेज़ . की सूची सम्मिलित करती है वांछित संग्रह . में ऑब्जेक्ट . साथ ही, यह संभव है कि बैच ऑपरेशन आंशिक रूप से विफल हो जाए। उस स्थिति में, हम सम्मिलित किए गए दस्तावेज़ों की संख्या कारण . की जाँच करके वापस कर सकते हैं अपवाद . के :

private int insertInto(String collection, List<Document> mongoDocs) {
    try {
        Collection<Document> inserts = mongo.insert(mongoDocs, collection);
        return inserts.size();
    } catch (DataIntegrityViolationException e) {
        if (e.getCause() instanceof MongoBulkWriteException) {
            return ((MongoBulkWriteException) e.getCause())
              .getWriteResult()
              .getInsertedCount();
        }
        return 0;
    }
}

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

public String importTo(String collection, List<String> jsonLines) {
    List<Document> mongoDocs = generateMongoDocs(jsonLines);
    int inserts = insertInto(collection, mongoDocs);
    return inserts + "/" + jsonLines.size();
}

4. मामलों का उपयोग करें

अब जब हम इनपुट को प्रोसेस करने के लिए तैयार हैं, तो हम कुछ उपयोग के मामले बना सकते हैं। आइए ImportUtils बनाएं इसमें हमारी मदद करने के लिए कक्षा। यह वर्ग इनपुट को JSON की पंक्तियों में बदलने के लिए जिम्मेदार होगा। इसमें केवल स्थिर विधियां होंगी। आइए एक साधारण स्ट्रिंग को पढ़ने के लिए शुरू करते हैं :

public static List<String> lines(String json) {
    String[] split = json.split("[\\r\\n]+");
    return Arrays.asList(split);
}

चूंकि हम एक सीमांकक के रूप में लाइन ब्रेक का उपयोग कर रहे हैं, रेगेक्स स्ट्रिंग्स को कई लाइनों में तोड़ने के लिए बहुत अच्छा काम करता है। यह रेगेक्स यूनिक्स और विंडोज लाइन एंडिंग्स दोनों को संभालता है। इसके बाद, फ़ाइल को स्ट्रिंग्स की सूची में बदलने की एक विधि:

public static List<String> lines(File file) {
    return Files.readAllLines(file.toPath());
}

इसी तरह, हम एक क्लासपाथ संसाधन को सूची में बदलने के लिए एक विधि के साथ समाप्त करते हैं:

public static List<String> linesFromResource(String resource) {
    Resource input = new ClassPathResource(resource);
    Path path = input.getFile().toPath();
    return Files.readAllLines(path);
}

4.1. सीएलआई के साथ स्टार्टअप के दौरान फ़ाइल आयात करें

हमारे पहले उपयोग के मामले में, हम एप्लिकेशन तर्कों के माध्यम से फ़ाइल आयात करने के लिए कार्यक्षमता लागू करेंगे। हम स्प्रिंग बूट का लाभ उठाएंगे ApplicationRunner बूट समय पर ऐसा करने के लिए इंटरफ़ेस। उदाहरण के लिए, हम आयात करने के लिए फ़ाइल को परिभाषित करने के लिए कमांड लाइन पैरामीटर पढ़ सकते हैं:

@SpringBootApplication
public class SpringBootJsonConvertFileApplication implements ApplicationRunner {
    private static final String RESOURCE_PREFIX = "classpath:";

    @Autowired
    private ImportJsonService importService;

    public static void main(String ... args) {
        SpringApplication.run(SpringBootPersistenceApplication.class, args);
    }

    @Override
    public void run(ApplicationArguments args) {
        if (args.containsOption("import")) {
            String collection = args.getOptionValues("collection")
              .get(0);

            List<String> sources = args.getOptionValues("import");
            for (String source : sources) {
                List<String> jsonLines = new ArrayList<>();
                if (source.startsWith(RESOURCE_PREFIX)) {
                    String resource = source.substring(RESOURCE_PREFIX.length());
                    jsonLines = ImportUtils.linesFromResource(resource);
                } else {
                    jsonLines = ImportUtils.lines(new File(source));
                }
                
                String result = importService.importTo(collection, jsonLines);
                log.info(source + " - result: " + result);
            }
        }
    }
}

getOptionValues() का उपयोग करना हम एक या अधिक फाइलों को संसाधित कर सकते हैं। ये फ़ाइलें या तो हमारे क्लासपाथ से या हमारे फाइल सिस्टम से हो सकती हैं। हम RESOURCE_PREFIX . का उपयोग करके उनमें अंतर करते हैं . “क्लासपाथ: . से शुरू होने वाला हर तर्क "फ़ाइल सिस्टम के बजाय हमारे संसाधन फ़ोल्डर से पढ़ा जाएगा। उसके बाद, वे सभी वांछित संग्रह . में आयात किए जाएंगे ।

आइए src/main/resources/data.json.log के अंतर्गत एक फ़ाइल बनाकर हमारे एप्लिकेशन का उपयोग शुरू करें :

{"name":"Book A", "genre": "Comedy"}
{"name":"Book B", "genre": "Thriller"}
{"name":"Book C", "genre": "Drama"}

निर्माण के बाद, हम इसे चलाने के लिए निम्नलिखित उदाहरण का उपयोग कर सकते हैं (पठनीयता के लिए जोड़े गए लाइन ब्रेक)। हमारे उदाहरण में, दो फाइलें आयात की जाएंगी, एक क्लासपाथ से, और एक फाइल सिस्टम से:

java -cp target/spring-boot-persistence-mongodb/WEB-INF/lib/*:target/spring-boot-persistence-mongodb/WEB-INF/classes \
  -Djdk.tls.client.protocols=TLSv1.2 \
  com.baeldung.SpringBootPersistenceApplication \
  --import=classpath:data.json.log \
  --import=/tmp/data.json \
  --collection=books

4.2. HTTP पोस्ट अपलोड से JSON फ़ाइल

इसके अतिरिक्त, यदि हम एक REST नियंत्रक बनाते हैं, तो हमारे पास JSON फ़ाइलें अपलोड और आयात करने के लिए एक समापन बिंदु होगा। उसके लिए, हमें एक मल्टीपार्टफाइल की आवश्यकता होगी पैरामीटर:

@RestController
@RequestMapping("/import-json")
public class ImportJsonController {
    @Autowired
    private ImportJsonService service;

    @PostMapping("/file/{collection}")
    public String postJsonFile(@RequestPart("parts") MultipartFile jsonStringsFile, @PathVariable String collection)  {
        List<String> jsonLines = ImportUtils.lines(jsonStringsFile);
        return service.importTo(collection, jsonLines);
    }
}

अब हम इस तरह के POST के साथ फ़ाइलें आयात कर सकते हैं, जहाँ “/tmp/data.json ” एक मौजूदा फ़ाइल को संदर्भित करता है:

curl -X POST http://localhost:8082/import-json/file/books -F "[email protected]/tmp/books.json"

4.3. JSON को एक विशिष्ट जावा प्रकार से मैप करना

हम केवल JSON का उपयोग कर रहे हैं, किसी भी प्रकार के लिए बाध्य नहीं है, जो MongoDB के साथ काम करने के फायदों में से एक है। अब हम अपने इनपुट की पुष्टि करना चाहते हैं। इस मामले में, आइए एक ऑब्जेक्टमैपर जोड़ें हमारी सेवा में यह परिवर्तन करके:

private <T> List<Document> generateMongoDocs(List<String> lines, Class<T> type) {
    ObjectMapper mapper = new ObjectMapper();

    List<Document> docs = new ArrayList<>();
    for (String json : lines) {
        if (type != null) {
            mapper.readValue(json, type);
        }
        docs.add(Document.parse(json));
    }
    return docs;
}

इस तरह, यदि टाइप पैरामीटर निर्दिष्ट है, हमारे मैपर हमारे JSON स्ट्रिंग को उस प्रकार के रूप में पार्स करने का प्रयास करेंगे। और, डिफ़ॉल्ट कॉन्फ़िगरेशन के साथ, यदि कोई अज्ञात गुण मौजूद है तो एक अपवाद फेंक देगा। MongoDB रिपॉजिटरी के साथ काम करने के लिए हमारी सरल बीन परिभाषा यहां दी गई है:

@Document("books")
public class Book {
    @Id
    private String id;
    private String name;
    private String genre;
    // getters and setters
}

और अब, हमारे दस्तावेज़ जनरेटर के उन्नत संस्करण का उपयोग करने के लिए, आइए इस पद्धति को भी बदलें:

public String importTo(Class<?> type, List<String> jsonLines) {
    List<Document> mongoDocs = generateMongoDocs(jsonLines, type);
    String collection = type.getAnnotation(org.springframework.data.mongodb.core.mapping.Document.class)
      .value();
    int inserts = insertInto(collection, mongoDocs);
    return inserts + "/" + jsonLines.size();
}

अब, एक संग्रह का नाम देने के बजाय, हम एक कक्षा . पास करते हैं . हम मानते हैं कि उसके पास दस्तावेज़ है एनोटेशन जैसा कि हमने अपनी पुस्तक . में उपयोग किया है , इसलिए यह संग्रह का नाम पुनः प्राप्त कर सकता है। हालांकि, एनोटेशन और दस्तावेज़ . दोनों के बाद से कक्षाओं का एक ही नाम है, हमें पूरा पैकेज निर्दिष्ट करना होगा।


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. दस्तावेज़ डेटाबेस:अनावश्यक डेटा, संदर्भ, आदि (विशेष रूप से MongoDB)

  2. MongoDB के मानचित्र-परिणामों की संरचना को कैसे बदलें?

  3. MongoDB में JavaScript NoSQL इंजेक्शन की रोकथाम

  4. क्लस्टर नियंत्रण के साथ MongoDB 4.0 की निगरानी और संचालन प्रबंधन

  5. नेवला, एक्सप्रेस, NodeJS के साथ अद्यतन मॉडल