【仅供内部供应商使用,不提供对外解答和培训】

Page tree

【仅供内部供应商使用,不提供对外解答和培训】

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 12 Current »

接口作用

MongoDB中,列的类型不同(Array类型,Object类型),在转换成为二维表的时候,就会有不同的处理方式。

从MongoDB数据集插件8.4+版本,提供接口可自行开发插件,处理更为复杂的类型的列。

接口内容

ColumnResolver
public interface ColumnResolver extends Mutable {

    String MARK_STRING = "ColumnResolver";

    int CURRENT_LEVEL = 1;


    boolean checkIfConditionMeet(ColumnResolver resolver);

    /**
     * 是否需要处理该类型的元素
     *
     * @param cell doc查询出来的对象
     * @return 需要做扩展处理则返回true,否则返回false
     */
    boolean accept(Object cell);

    /**
     * 增加新的列
     *
     * @param key  列名
     * @param cell 内容
     */
    List<FieldObject> expandColumn(String key, Object cell);


    /**
     * 扩展特殊列,增加新的行
     *
     * @param doc                 MongoDB的文档查询对象
     * @param columnNames         列名集合
     * @param columnResolverMap 需要特殊处理的列以及处理器集合
     * @param rowDataCollections  扩展出来的行数据集合
     * @param rowData             当前行数据
     */
    void expandData(Document doc, List<String> columnNames,
                    Map<FieldObject, ColumnResolver> columnResolverMap,
                    List<List<Object>> rowDataCollections,
                    List<Object> rowData);
}

示例实现(数组类型)

我们以数组元素为例子,面对这样的数据结构:

带数组元素的JSON结构
{ 
    "name" : "李四", 
    "age" : 15, 
    "language" : [
        "英语", 
        "数学", 
        "物理"
    ], 
    "region" : [
        "新疆", 
        "海南", 
        "台湾"
    ], 
    "country" : "US"
}

当需要把表格转换为二维表的时候,就需要处理language和region这样的数组元素,可以通过实现接口com.fr.plugin.db.mongo.expand.ColumnResolver,来把数组自动扩张开,示例代码如下:

处理数组元素的示例代码
public class ArrayColumnResolver extends AbstractColumnResolver {

    @Override
    public boolean accept(Object cell) {
        return cell instanceof ArrayList
                && !(((ArrayList) cell).get(0) instanceof Document);
    }


    @Override
    public List<FieldObject> expandColumn(String key, Object cell) {
        List<FieldObject> data = new ArrayList<FieldObject>();
         data.add(FieldObject.create(key));
         return data;
    }

    @Override
    public void expandData(Document doc, List<String> columnNames, Map<FieldObject, ColumnResolver> columnResolverMap, 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 (Map.Entry<FieldObject, ColumnResolver> entry : columnResolverMap.entrySet()) {
            if (!checkIfConditionMeet(entry.getValue())) {
                continue;
            }
            FieldObject fieldObject = entry.getKey();
            Object data = doc.get(fieldObject.getOriginalName());
            if (data instanceof ArrayList) {
                List<Object> array = (List<Object>) data;
                if (standard == null) {
                    standard = array;
                }
                maxLength = Math.max(maxLength, array.size());
                group.put(fieldObject.getIndex(), 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 (FieldObject fieldObject : columnResolverMap.keySet()) {
                    List<Object> array = group.get(fieldObject.getIndex());
                    row.set(fieldObject.getIndex(), array.size() > i ? array.get(i) : 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插件和列处理插件,就可以实现自已的要求了。

 

  • No labels