node.js oracledb - получает по одной записи на группу с массивом.
Я использую node.js и OracleDB для объединения двух таблиц с отношением один ко многим.
Например:
RECORDS Table:
RECORD_ID COMMENTS
1000 Comment 1
1001 Comment 2
Таблица УСТРОЙСТВА:
DEVICE_ID REF_RECORD_ID DEVICE_NAME
2000 1000 iPhone 6
2001 1000 iPhone 7
2003 1001 Samsung Galaxy S6
2004 1001 Samsung Galaxy S7
Я могу получить соединение, используя
SELECT A.RECORD_ID, A.COMMENT, B.DEVICE_ID, B.DEVICE_NAME FROM RECORDS A, DEVICES B WHERE A.RECORD_ID = B.REF_RECORD_ID;
Текущий результат:
[{
RECORD_ID: 1000, COMMENT: "Comment 1", DEVICE_ID: 2000, DEVICE_NAME: "iPhone 6"
},
{
RECORD_ID: 1000, COMMENT: "Comment 1", DEVICE_ID: 2001, DEVICE_NAME: "iPhone 7"
},
{
RECORD_ID: 1001, COMMENT: "Comment 2", DEVICE_ID: 2003, DEVICE_NAME: "Samsung Galaxy S6"
},
{
RECORD_ID: 1001, COMMENT: "Comment 2", DEVICE_ID: 2004, DEVICE_NAME: "Samsung Galaxy S7"
}]
Но я хотел бы получить результат, показанный ниже:
[{
RECORD_ID: 1000, COMMENT: "Comment 1",
DEVICES: [{ DEVICE_ID: 2000, DEVICE_NAME: "iPhone 6" }, { DEVICE_ID: 2001, DEVICE_NAME: "iPhone 7" }]
},
{
RECORD_ID: 1001, COMMENT: "Comment 2",
DEVICES: [{ DEVICE_ID: 2003, DEVICE_NAME: "Samsung Galaxy S6" }, { DEVICE_ID: 2004, DEVICE_NAME: "Samsung Galaxy S7" }]
}]
Есть ли лучший способ сделать это, вместо того, чтобы циклически перебирать массив объектов, а затем находить дубликаты RECORD_ID и создавать массив для проталкивания субэлементов?
1 ответ
Заданный вами вывод может быть выполнен напрямую, когда поддерживаются вложенные выражения курсора. Вы можете видеть, что другие ищут то же самое здесь: https://github.com/oracle/node-oracledb/issues/565
А пока вот пример кода, который может сделать это в Node.js, как только вы получите набор результатов:
var resultRowsIdx;
var resultRows = [{
RECORD_ID: 1000, COMMENT: "Comment 1", DEVICE_ID: 2000, DEVICE_NAME: "iPhone 6"
},
{
RECORD_ID: 1000, COMMENT: "Comment 1", DEVICE_ID: 2001, DEVICE_NAME: "iPhone 7"
},
{
RECORD_ID: 1001, COMMENT: "Comment 2", DEVICE_ID: 2003, DEVICE_NAME: "Samsung Galaxy S6"
},
{
RECORD_ID: 1001, COMMENT: "Comment 2", DEVICE_ID: 2004, DEVICE_NAME: "Samsung Galaxy S7"
}];
var records = [];
var recordsMap = {};
var currentRecordId;
for (resultRowsIdx = 0; resultRowsIdx < resultRows.length; resultRowsIdx += 1) {
currentRecordId = resultRows[resultRowsIdx].RECORD_ID;
if (!recordsMap[currentRecordId]) {
recordsMap[currentRecordId] = {};
recordsMap[currentRecordId].RECORD_ID = currentRecordId;
recordsMap[currentRecordId].COMMENT = resultRows[resultRowsIdx].COMMENT;
recordsMap[currentRecordId].DEVICES = [];
records.push(recordsMap[currentRecordId]);
}
recordsMap[currentRecordId].DEVICES.push({
DEVICE_ID: resultRows[resultRowsIdx].DEVICE_ID,
DEVICE_NAME: resultRows[resultRowsIdx].DEVICE_NAME
});
}
console.log(records);