Создайте файл CSV из marklogic с помощью Java Client Api(DMSDK)
Я хочу создать CSV-файл для 1,3M записей из моей базы данных marklogic. Я попытался использовать CORB для этого, но это заняло больше времени, чем я ожидал. Мои данные такие
{
"One": {
"Name": "One",
"Country": "US"
},
"Two": {
"State": "kentucky"
},
"Three": {
"Element1": "value1",
"Element2": "value2",
"Element3": "value3",
"Element4": "value4",
so on ...
}
}
Ниже приведены мои модули Corb
Selector.xqy
var total = cts.uris("", null, cts.collectionQuery("data"));
fn.insertBefore(total,0,fn.count(total))
Transform.xqy (где я храню все элементы в массиве)
var name = fn.tokenize(URI, ";");
const node = cts.doc(name);
var a= node.xpath("/One/*");
var b= node.xpath("/Two/*");
var c= node.xpath("/Three/*");
fn.stringJoin([a, b, c,name], " , ")
мой файл свойств
THREAD-COUNT=16
BATCH-SIZE=1000
URIS-MODULE=selector.sjs|ADHOC
PROCESS-MODULE=transform.sjs|ADHOC
PROCESS-TASK=com.marklogic.developer.corb.ExportBatchToFileTask
EXPORT-FILE-NAME=Report.csv
PRE-BATCH-TASK=com.marklogic.developer.corb.PreBatchUpdateFileTask
EXPORT-FILE-TOP-CONTENT=Col1,col2,....col16 -- i have 16 columns
Создание CSV-файла заняло более 1 часа. А также для попытки в кластере мне нужно сначала настроить балансировщик нагрузки. В то время как Java Client api будет распределять работу по всем узлам без какого-либо балансировщика нагрузки.
Как я могу реализовать то же самое в Java Client APi, я знаю, что могу запустить модуль преобразования с помощью ServerTransform
а также ApplyTransformListener
,
public static void main(String[] args) {
// TODO Auto-generated method stub
DatabaseClient client = DatabaseClientFactory.newClient
("localhost", pwd, "x", "x", DatabaseClientFactory.Authentication.DIGEST);
ServerTransform txform = new ServerTransform("tsm"); -- Here i am implementing same logic of above `tranform module` .
QueryManager qm = client.newQueryManager();
StructuredQueryBuilder query = qm.newStructuredQueryBuilder();
query.collection();
DataMovementManager dmm = client.newDataMovementManager();
QueryBatcher batcher = dmm.newQueryBatcher(query.collections("data"));
batcher.withBatchSize(2000)
.withThreadCount(16)
.withConsistentSnapshot()
.onUrisReady(
new ApplyTransformListener().withTransform(txform))
.onBatchSuccess(batch-> {
System.out.println(
batch.getTimestamp().getTime() +
" documents written: " +
batch.getJobWritesSoFar());
})
.onBatchFailure((batch,throwable) -> {
throwable.printStackTrace();
});
// start the job and feed input to the batcher
dmm.startJob(batcher);
batcher.awaitCompletion();
dmm.stopJob(batcher);
client.release();
}
Но как я могу отправить заголовок файла CSV, как тот, в CORB(т.е. EXPORT-FILE-TOP-CONTENT) . Есть ли документация для реализации CSV
файл? Какой класс будет реализовывать это?
Любая помощь приветствуется
Спасибо
1 ответ
Вероятно, самый простой вариант - это экспорт данных в CSV, который использует Java Client API и DMSDK.
Обратите внимание, что вы, вероятно, захотите установить REST-преобразование на стороне сервера, чтобы извлекать только те данные, которые вы хотите получить в выводе CSV, вместо того, чтобы загружать все содержимое документа, а затем извлекать его на стороне Java.
Рабочий пример кода, необходимого для использования DMSDK и создания сводного CSV (один CSV для всех записей), см. В разделе ExporToWriterListenerTest.testMassExportToWriter. Ради SO вот фрагмент кода (с небольшим изменением упрощения, включая написание заголовков столбцов (непроверенный код)):
try (FileWriter writer = new FileWriter(outputFile)) {
writer.write("uri,collection,contents");
writer.flush();
ExportToWriterListener exportListener = new ExportToWriterListener(writer)
.withRecordSuffix("\n")
.withMetadataCategory(DocumentManager.Metadata.COLLECTIONS)
.onGenerateOutput(
record -> {
String uri = record.getUri();
String collection = record.getMetadata(new DocumentMetadataHandle()).getCollections().iterator().next();
String contents = record.getContentAs(String.class);
return uri + "," + collection + "," + contents;
}
);
QueryBatcher queryJob =
moveMgr.newQueryBatcher(query)
.withThreadCount(5)
.withBatchSize(10)
.onUrisReady(exportListener)
.onQueryFailure( throwable -> throwable.printStackTrace() );
moveMgr.startJob( queryJob );
queryJob.awaitCompletion();
moveMgr.stopJob( queryJob );
}
Однако, если вы не знаете, что в вашем контенте нет двойных кавычек, символов новой строки или символов, отличных от ascii, рекомендуется использовать библиотеку CSV, чтобы убедиться, что ваш вывод правильно экранирован. Чтобы использовать библиотеку CSV, вы, конечно, можете использовать любой учебник для вашей библиотеки. Вам не нужно беспокоиться о безопасности потоков, потому что ExportToWriterListener запускает ваши слушатели в синхронизированном блоке, чтобы предотвратить наложение записей в записывающее устройство. Вот пример использования одной библиотеки CSV, Jackson CsvMapper.
Обратите внимание, что вам не нужно использовать ExportToWriterListener .,, Вы можете использовать его в качестве отправной точки, чтобы написать свой собственный слушатель. В частности, поскольку ваша основная задача - производительность, вы можете попросить своих слушателей записать в один файл по одному потоку, а затем выполнить постобработку, чтобы объединить все вместе. Тебе решать.