Don't despair, as with most OR related things in mongo you can always write yourself a codec. Would have been useful to provide some details how you currently handle your OR mapping, but I found the docs or the implementation of the native codecs (especially DocumentCodec) very helpful in figuring out how to implement and use them.
This is a codec I am using to persist an array of floats without making use of a Collection. Please note, that this always creates a float[] array of fixed size. If you have different needs, you would still need to figure out a way to determine and preallocate the needed memory. Code below will fail badly if you try to store larger arrays than it expects. Secondly, afaik mongo does not store floats, but doubles, so there will inevitably be some conversion.
AbstractCodec is our own implementation of commonly used methods e.g. readValue(), writeObject() to store and read various types. They were heavily inspired by the java driver implementation, so that should be a good starting point if codecs are new to you.
public class WaveformCodec extends AbstractCodec implements Codec<Waveform> {
public WaveformCodec(CodecRegistry registry, BsonTypeClassMap bsonTypeClassMap) {
super(registry, bsonTypeClassMap);
}
@Override
public Waveform decode(BsonReader reader, DecoderContext decoderContext) {
ObjectId id = null;
float[] data = new float[5120];
reader.readStartDocument();
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
String fieldName = reader.readName();
switch (fieldName) {
case "_id":
id = (ObjectId) readValue(reader, ObjectId.class, decoderContext);
break;
case "data":
reader.readStartArray();
int i = 0;
while (reader.readBsonType() != BsonType.END_OF_DOCUMENT) {
data[i++] = (float) reader.readDouble();
}
reader.readEndArray();
break;
default:
throw new RuntimeException("unknown field in WaveformCodec: " + fieldName);
}
}
reader.readEndDocument();
return new Waveform(id, data);
}
@Override
public void encode(BsonWriter writer, Waveform waveform, EncoderContext encoderContext) {
writer.writeStartDocument();
writeObject(writer, "_id", ObjectId.class, waveform.getId(), encoderContext);
writer.writeName("data");
writer.writeStartArray();
for (float value : waveform.getData()) {
writer.writeDouble(value);
}
writer.writeEndArray();
writer.writeEndDocument();
}
@Override
public Class<Waveform> getEncoderClass() {
return Waveform.class;
}
}
And this is the class we are effectively persisting:
public class Waveform {
private ObjectId id;
private float[] data;
public Waveform(ObjectId id, float[] data) {
this.id = id;
this.data = data;
}
public ObjectId getId() {
return id;
}
public void setId(ObjectId id) {
this.id = id;
}
public float[] getData() {
return data;
}
}
Now you just need to register your codec with the driver, and you should be able to enjoy typed collections.