Не отчаивайтесь, так как с большинством связанных с ИЛИ вещей в монго вы всегда можете написать себе кодек. Было бы полезно предоставить некоторые подробности о том, как вы в настоящее время обрабатываете свое сопоставление ИЛИ, но я нашел, что документы или реализация нативных кодеков (особенно DocumentCodec) очень полезны для выяснения того, как их реализовать и использовать.
Это кодек, который я использую для сохранения массива с плавающей точкой без использования коллекции. Обратите внимание, что при этом всегда создается массив float[]
фиксированного размера. Если у вас есть другие потребности, вам все равно нужно найти способ определить и предварительно выделить необходимую память. Код ниже потерпит неудачу, если вы попытаетесь сохранить массивы большего размера, чем это ожидается. Во-вторых, afaik mongo не хранит числа с плавающей запятой, но удваивается, поэтому неизбежно произойдет некоторое преобразование.
AbstractCodec - наша собственная реализация часто используемых методов, например readValue()
, writeObject()
для хранения и чтения различных типов. Они были в значительной степени вдохновлены реализацией драйвера Java, так что это должно быть хорошей отправной точкой, если кодеки являются новыми для вас.
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;
}
}
И этот класс мы эффективно сохраняем:
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;
}
}
Теперь вам просто нужно зарегистрировать свой кодек в драйвере, и вы сможете пользоваться набранными наборами.