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

Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

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

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

...

Code Block
titleColumnResolver
collapsetrue
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;


    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 waitingColumnsIndexcolumnResolverMap 需要特殊处理的列集合需要特殊处理的列以及处理器集合
     * @param rowDataCollections  扩展出来的行数据集合
     * @param rowData             当前行数据
     */
    void expandData(Document doc, List<String> columnNames,
                    Map<FieldObject, List<Integer>ColumnResolver> waitingColumnsIndex, columnResolverMap,
                    List<List<Object>> rowDataCollections,
                    List<Object> rowData);
}

示例实现(数组类型)

...

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

import java.util.*;

public class ArrayColumnResolver extends AbstractColumnResolver {

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

    @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++&& !(((ArrayList) cell).get(0) instanceof Document);
    }


    @Override
    public List<FieldObject> expandColumn(String key, Object cell) {
        List<FieldObject>        List<Object> row data = new ArrayList<Object>(Arrays.asList(new Object[rowData.size()]))ArrayList<FieldObject>();
                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);
    data.add(FieldObject.create(key));
        }
        }
    }
}

示例实现(对象类型)

面对这样的数据结构:

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

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

...

title处理Map元素的示例代码
collapsetrue

...

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

注册方式

Code Block
<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插件和列处理插件,就可以实现自已的要求了。

...