【仅供内部供应商使用,不提供对外解答和培训】
【仅供内部供应商使用,不提供对外解答和培训】
MongoDB中,列的类型不同(Array类型,Object类型),在转换成为二维表的时候,就会有不同的处理方式。
从MongoDB数据集插件8.3+版本,提供接口可自行开发插件,处理更为复杂的类型的列。
package com.fr.plugin.db.mongo.expand; import com.fr.stable.fun.mark.Mutable; import org.bson.Document; import java.util.List; public interface ColumnResolver extends Mutable { String MARK_STRING = "ColumnResolver"; int CURRENT_LEVEL = 1; /** * 是否需要处理该类型的元素 * * @param cell doc查询出来的对象 * @return 需要做扩展处理则返回true,否则返回false */ boolean accept(Object cell); /** * 扩展特殊列,增加新的行 * * @param doc MongoDB的文档查询对象 * @param columnNames 列民集合 * @param waitingColumnsIndex 需要特殊处理的列集合 * @param rowDataCollections 扩展出来的行数据集合 * @param rowData 当前行数据 */ void expandData(Document doc, List<String> columnNames, List<Integer> waitingColumnsIndex, List<List<Object>> rowDataCollections, List<Object> rowData); }
我们以数组元素为例子,面对这样的数据结构:
当需要把表格转换为二维表的时候,就需要处理language和region这样的数组元素,可以通过实现接口com.fr.plugin.db.mongo.expand.ColumnResolver,来把数组自动扩张开,示例代码如下:
面对这样的数据结构:
当需要把表格转换为二维表的时候,就需要处理name这样的Object类型的列,可以看出name是一个HashMap类型的结构,所以可以实现一个MapColumnResolver处理器,用于处理这一类的列:
import org.bson.Document; import java.util.*; public class MapColumnResolver extends AbstractColumnResolver { @Override public boolean accept(Object cell) { return cell instanceof Document; } @Override public void expandData(Document doc, List<String> columnNames, List<Integer> waitingColumnsIndex, List<List<Object>> rowDataCollections, List<Object> rowData) { Map<Integer, List<Object>> group = new HashMap<Integer, List<Object>>(); List<Object> standard = null; int maxLength = 0; for (int index : waitingColumnsIndex) { Object data = doc.get(columnNames.get(index)); if (data instanceof Document) { Document document = (Document)data; List<Object> array = new ArrayList<Object>(); if (standard == null) { for (Map.Entry<String, Object> entry : document.entrySet()) { array.add(entry); } standard = array; } maxLength = Math.max(maxLength, array.size()); group.put(index, array); } } if (standard != null) { for (int i = 0; i < maxLength; i++) { List<Object> row = new ArrayList<Object>(Arrays.asList(new Object[rowData.size()])); Collections.copy(row, rowData); for (int index : waitingColumnsIndex) { List<Object> array = group.get(index); Map.Entry<String, Object> el = (Map.Entry<String, Object>)array.get(i); row.set(index, array.size() > i ? el.getValue() : null); } rowDataCollections.add(row); } } } }
<dependence> <Item key="com.fr.solution.plugin.db.mongo" type="plugin"/> </dependence> <extra-core> <ColumnResolver class="com.fr.plugin.db.mongo.expand.impl.ArrayColumnResolver"/> </extra-core>
同时安装MongoDB插件和列处理插件,就可以实现自已的要求了。