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

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 10 Next »

接口作用

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);
}

示例实现(数组类型)

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

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

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

处理数组元素的示例代码
import org.bson.Document;

import java.util.*;

public class ArrayColumnResolver extends AbstractColumnResolver {

    @Override
    public boolean accept(Object cell) {
        return cell instanceof List;
    }

    @Override
    public void expandData(Document doc, List<String> columnNames, List<Integer> waitingColumnsIndex, List<List<Object>> rowDataCollections, List<Object> rowData) {
        fillRowDataByArray(doc, columnNames, waitingColumnsIndex, rowDataCollections, rowData);
    }

    private void fillRowDataByArray(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 List) {
                List<Object> array = (List<Object>) data;
                if (standard == null) {
                    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);
                    row.set(index, array.size() > i ? array.get(i) : null);
                }
                rowDataCollections.add(row);
            }
        }
    }
}

示例实现(对象类型)

面对这样的数据结构:

对象类型的数据结构
{ 
    "value" : "word", 
    "name" : {
        "O" : "XXX", 
        "P" : "YYY"
    }
}

当需要把表格转换为二维表的时候,就需要处理name这样的Object类型的列,可以看出name是一个HashMap类型的结构,所以可以实现一个MapColumnResolver处理器,用于处理这一类的列:

处理Map元素的示例代码
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插件和列处理插件,就可以实现自已的要求了。

 

  • No labels