在MongoDB / Morphia中检索数组数组?

我想在MongodDB中以以下格式存储文档:

{
    "_id" : ObjectId("563f904cd2a56e3934484c52"),
    "data" : [ 
        [ 
            "Year", 
            "Profit"
        ], 
        [ 
            "2015", 
            2
        ]
    ]
}

我创建了一个适合结构的POJO.

import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;

import java.util.List;


@Entity(noClassnameStored = true)
public class Document {
    @Id
    private ObjectId id;
    private List<List<Object>> data;

    public ObjectId getId() {
        return id;
    }

    public void setId(ObjectId id) {
        this.id = id;
    }

    public List<List<Object>> getData() {
        return data;
    }

    public void setData(List<List<Object>> data) {
        this.data = data;
    }
}

当我插入数据库时​​,一切正常,我可以看到插入的数据.

List<List<Object>> data= Arrays.asList(Arrays.asList("Year", "Profit"),Arrays.asList("2015", 100));
    Document document = new Document();
    document.setData(data);
    ds.save(c);

但是当我尝试检索它时:

Document documentRetrieved = ds.find(Document.class).get();

我得到以下异常:

java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassCastException: java.lang.String cannot be cast to com.mongodb.DBObject
    at org.mongodb.morphia.mapping.EmbeddedMapper.fromDBObject(EmbeddedMapper.java:173)
    at org.mongodb.morphia.mapping.Mapper.readMappedField(Mapper.java:642)
    at org.mongodb.morphia.mapping.Mapper.fromDb(Mapper.java:617)
    at org.mongodb.morphia.mapping.Mapper.fromDBObject(Mapper.java:310)
    at org.mongodb.morphia.query.MorphiaIterator.convertItem(MorphiaIterator.java:87)
    at org.mongodb.morphia.query.MorphiaIterator.processItem(MorphiaIterator.java:73)
    at org.mongodb.morphia.query.MorphiaIterator.next(MorphiaIterator.java:68)
    at org.mongodb.morphia.query.QueryImpl.get(QueryImpl.java:421)

有没有办法以List< List< Object>>的形式检索数据? ?

最佳答案 我已经为我创建了一个转换器,例如:

import com.mongodb.BasicDBObject;
import org.bson.types.BasicBSONList;
import org.mongodb.morphia.converters.TypeConverter;
import org.mongodb.morphia.mapping.MappedField;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class MyCustomDataConverter extends TypeConverter {
    @Override
    public Object decode(Class<?> targetClass, Object fromDBObject, MappedField optionalExtraInfo) {
        BasicDBObject obj = (BasicDBObject) fromDBObject;

        BasicBSONList colsArr = (BasicBSONList) obj.get("cols");
        List<String> cols = colsArr.stream()
                .map(c -> (String) c)
                .collect(Collectors.toList());

        BasicBSONList rowsArr = (BasicBSONList) obj.get("rows");
        List<List<?>> rows = rowsArr.stream()
                .map(rowObj -> (BasicBSONList) rowObj)
                .map(ArrayList::new)
                .collect(Collectors.toList());

        return new MyCustomData(cols, rows);
    }

    @Override
    public Object encode(Object value, MappedField optionalExtraInfo) {
        MyCustomData data = (MyCustomData) value;

        BasicDBObject obj = new BasicDBObject();
        obj.put("cols", list(data.columns()));

        BasicBSONList rowsObj = new BasicBSONList();
        for (List<?> row : data.data()) {
            rowsObj.add(list(row));
        }
        obj.put("rows", rowsObj);

        return obj;
    }

    private BasicBSONList list(List<?> elements) {
        BasicBSONList list = new BasicBSONList();
        list.addAll(elements);
        return list;
    }

    @Override
    protected boolean isSupported(Class<?> c, MappedField optionalExtraInfo) {
        return c == MyCustomData.class;
    }
}

哪里

import java.util.List;

public class MyCustomData {
    private final List<String> columns;
    private final List<List<?>> data;
    private MyCustomData() { // For Morphia
        this(null, null);
    }
    public MyCustomData(List<String> columns, List<List<?>> data) {
        this.columns = columns;
        this.data = data;
    }
    public List<String> columns() {
        return columns;
    }
    public List<List<?>> data() {
        return data;
    }
}

最后,我使用以下方式注册了转换器:

Morphia morphia = new Morphia();
morphia.getMapper().getConverters().addConverter(new MyCustomDataConverter() );
点赞