Записать потоковую коллекцию в файл Java-Mongo - PullRequest
0 голосов
/ 25 мая 2018

У меня есть сервер под управлением Monogdb, который также имеет коллекцию с именем mycoll.Новые документы вставляются в коллекцию постоянно.Мое намерение состоит в том, чтобы иметь локальный файл с копией всех документов коллекции.Мой текущий подход заключается в следующем:

String host = "myHost";
int port = 3717;
String user = "user";
String password = "pass";
String databaseName = "dbName";
String collectionName = "mycoll";

MongoCredential credential = MongoCredential.createCredential(user, databaseName, password.toCharArray());
MongoClient mongoClient = new MongoClient(new ServerAddress(host, port), Arrays.asList(credential));
MongoDatabase database = mongoClient.getDatabase(databaseName);
MongoCollection<Document> collection = database.getCollection(collectionName);
FindIterable<Document> cursor = collection.find();

String path = "./outputData.txt";


while(cursor.iterator().hasNext()){

        try(FileWriter fw = new FileWriter(path, true);
                BufferedWriter bw = new BufferedWriter(fw);
                PrintWriter out = new PrintWriter(bw))
        {
                out.println(cursor.iterator().next());
        } catch (IOException e) {
                System.out.println("Error writing to file.");
        }

}

Я знаю, что мог бы создать буфер для хранения данных и их последующей записи, но большая проблема все еще не решена: доступ к документам одинодним.Поэтому мой вопрос: как я мог получить доступ к нескольким документам одновременно, чтобы записать их в ./outputData.txt?

Ответы [ 4 ]

0 голосов
/ 30 мая 2018

Что я думаю, вам нужно много, как триггеры.MongoDB не имеет никакой поддержки триггеров, однако некоторые люди «свернули свои собственные», используя некоторые приемы.Ключевым моментом здесь является оплог.

Когда вы запускаете MongoDB в наборе реплик, все действия MongoDB записываются в журнал операций (известный как оплог).Оплог - это просто список изменений, внесенных в данные.Реплики Устанавливает функцию, слушая изменения в этом журнале операций и затем применяя изменения локально.

Вы также можете прочитать о настраиваемых курсорах.Кроме того, вы можете получить помощь в текущем проекте по той же проблеме:
https://github.com/deftlabs/mongo-java-tailable-cursor

0 голосов
/ 28 мая 2018

Вы также можете использовать Решение Spring Integration + MongoDB

23.4 Адаптер входящего канала MongoDB

Адаптер входящего канала MongoDb имеет значениепотребитель опроса, который считывает данные из MongoDb и отправляет их как полезную нагрузку сообщения.

<int-mongodb:inbound-channel-adapter id="mongoInboundAdapter"
       channel="replyChannel"
       query="{'name' : 'Bob'}"
       entity-class="java.lang.Object"
       auto-startup="false">
      <int:poller fixed-rate="100"/>
</int-mongodb:inbound-channel-adapter>

Пояснение

MongoDB Inbound Channel Adapter может непрерывно запрашивать вашу базу данных MongoDB и затем обрабатывать информациюделать с ней все, что вы хотите.

Несколько примеров вы найдете в документации.

Надеюсь, это поможет вам.

0 голосов
/ 29 мая 2018

Вы можете оптимизировать, используя Bulk Reads с .batchsize ().При извлечении данных с использованием курсора вы можете указать количество строк, извлекаемых в каждой операции, используя предложение batchSize .

пример:

FindIterable<Document> collection = database.getCollection(collectionName)
.find()
.batchSize(arraySize);
//if you want to read 10 documents at once, 
 //set arraySize to 10.. so on

for(Document doc : collection) {
      //  save to file
     }

Обратите внимание, что batchSizeОператор на самом деле не возвращает массив в программу - он просто контролирует количество документов, полученных в каждом цикле передачи по сети.Все это происходит «под капотом» с точки зрения ваших программ. Надеюсь, что эта справка

Подробнее о пакетном размере вы можете прочитать на https://docs.mongodb.com/manual/reference/method/cursor.batchSize/

0 голосов
/ 28 мая 2018

Проще говоря, просто верните MongoCursor, вызвав iterator() "один раз", потому что это все, что вам нужно сделать.

Затем очень просто создайте свой дескриптор файла "вне" цикла,Единственное, что действительно принадлежит «внутри» цикла - это фактическая итерация и запись курсора.

try {    

  MongoCursor<Document> cursor = collection.find().iterator();
  String path = "./outputData.txt";

  PrintWriter out = new PrintWriter(
    new BufferedWriter(new FileWriter(path, true))
  );

  while(cursor.hasNext()){
    out.println(cursor.next().toJson());
  }

  out.flush();            // flush to ensure writes
  out.close();            // close the handle when done

} catch (IOException e) {
  System.out.println("Error writing to file.");
}

Как только вы закончите с курсором, просто закройте возвращенный дескриптор файла.

Всевам действительно нужно знать, что вы не «создаете» файловый дескриптор и не продолжаете открывать «внутри» цикла.Это то, что вы делаете один раз, а затем просто «записываете» любым способом для каждой итерации.


В качестве полного списка вы можете запустить код, аналогичный перечисленному для локальной MongoDB.на порт по умолчанию без аутентификации.При необходимости добавьте параметры для изменения, но это «базовый» код, необходимый

import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;

public class Application {

    public static void main(String[] args) {

        PrintWriter out  = null;
        MongoClient mongoClient = null;

        try {

            mongoClient = new MongoClient();
            MongoDatabase db = mongoClient.getDatabase("test");
            MongoCollection<Document> collection = db.getCollection("sample");

            out = new PrintWriter(
                    new BufferedWriter(new FileWriter("output.txt"))
            );

            // Clear collection and insert data
            collection.deleteMany(new Document());
            collection.insertMany(Arrays.asList(
                    new Document("a", 1),
                    new Document("a", 2),
                    new Document("a", 3)
            ));

            MongoCursor<Document> cursor = collection.find().iterator();

            while ( cursor.hasNext() ) {
                out.println(cursor.next().toJson());
                //System.out.println(cursor.next().toJson());
            }

            out.flush();

        } catch(Exception e) {
            System.out.println(e.getMessage());
        } finally {
            if (out != null) {
                out.close();
            }
            if (mongoClient != null) {
                mongoClient.close();
            }
        }
    }
}

Создает новый файл при каждом запуске и выводит документы, которые вставляются в коллекцию.

Дает вам файл с чем-то вроде этого:

{ "_id" : { "$oid" : "5b0bd9576a6bfa1f30e6c320" }, "a" : 1 }
{ "_id" : { "$oid" : "5b0bd9576a6bfa1f30e6c321" }, "a" : 2 }
{ "_id" : { "$oid" : "5b0bd9576a6bfa1f30e6c322" }, "a" : 3 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...