Статьи

Создание коллекции MongoDB Capped на Java

В MongoDB можно сохранять порядок вставки документов в коллекцию по кругу. Эти типы коллекций называются Capped Collections в MongoDB. Документация MongoDB описывает ограниченные коллекции:

«Закрытые коллекции — это коллекции фиксированного размера, которые поддерживают высокопроизводительные операции, которые вставляют, извлекают и удаляют документы в зависимости от порядка вставки. Закрытые коллекции работают подобно кольцевым буферам: как только коллекция заполняет выделенное пространство, она освобождает место для новых документов, перезаписывая самые старые документы в коллекции ».

Итак, мы знаем, что такое ограниченная коллекция, но как ее создать?

Из оболочки MongoDB мы создали бы ограниченную коллекцию, используя команду db.createCollection :

1
2
3
db.createCollection("logs", {capped: true,
                             size: 4096,
                             max:5})

Эта команда сообщает MongoDB о создании коллекции под названием «logs» с максимальным размером 4096 байт, которая может содержать до 5 документов. Когда добавляется 6-й документ, первый документ удаляется из коллекции, гарантируя, что в коллекции будет максимум 5 документов. Параметр «size» является обязательным, однако параметр «max» является необязательным.

В Java есть два распространенных способа связи с MongoDB; драйвер Java MongoDB и с Morphia (легкая библиотека отображения типов для безопасного отображения объектов в / из MongoDB).

Во-первых, давайте сначала посмотрим на использование драйвера Java.

Драйвер Java

С драйвером Java снова мы используем команду db.createCollection , на этот раз передавая BasicDBObject в качестве параметра. Этот параметр имеет поля «capped», «size» и «max», которые указывают, что коллекция ограничена, максимальный размер коллекции в байтах и ​​максимальное количество записей в коллекции. В следующем фрагменте кода показано, как подключиться к локальному экземпляру MongoDB и создать ограниченную коллекцию.

01
02
03
04
05
06
07
08
09
10
11
12
MongoClient mongoClient = new MongoClient(new MongoClientURI("mongodb://localhost"));
DB db = mongoClient.getDB("test");
 
DBCollection collection;
if (!db.collectionExists("cappedLogsJavaDriver")) {
    BasicDBObject options = new BasicDBObject("capped", true);
    options.append("size", 4096);
    options.append("max", 5);
    collection = db.createCollection("cappedLogsJavaDriver", options);
} else {
    collection = db.getCollection("cappedLogsJavaDriver");
}

Создав коллекцию, мы можем вставить в нее документы, чтобы убедиться, что она работает должным образом. В следующем фрагменте кода показано, как вставить 8 документов в коллекцию (помните, что только последние 5 из них будут сохранены, поскольку это ограниченная коллекция).

1
2
3
4
for (int i = 0; i < 8; i++) {
    BasicDBObject logEntry = new BasicDBObject("logId", i);
    collection.insert(logEntry);
}

Используя интерактивную оболочку MongoDB, мы можем проверить, что документы, которые теперь хранятся в коллекции, соответствуют ожиданиям.

1
2
3
4
5
6
> db.cappedLogsJavaDriver.find()
{ "_id" : ObjectId("54a1ca44a82617da4f72e025"), "logId" : 3 }
{ "_id" : ObjectId("54a1ca44a82617da4f72e026"), "logId" : 4 }
{ "_id" : ObjectId("54a1ca44a82617da4f72e027"), "logId" : 5 }
{ "_id" : ObjectId("54a1ca44a82617da4f72e028"), "logId" : 6 }
{ "_id" : ObjectId("54a1ca44a82617da4f72e029"), "logId" : 7 }

морфий

Теперь, когда мы увидели, как создать коллекцию с помощью драйвера Java, давайте посмотрим, как мы можем добиться того же с помощью Morphia.

Суть Morphia заключается в отображении классов Java в / из MongoDB. Классы, которые мы хотим сохранить в MongoDB, аннотируются аннотацией @Entity , которая затем сохраняется в коллекции, обычно называемой в честь аннотируемого класса. Чтобы создать ограниченную коллекцию, мы должны добавить дополнительные значения в аннотацию @Entity чтобы указать максимальное количество записей в коллекции и размер коллекции. Моделируя объект того же типа, который использовался в примере для драйвера Java, мы создали бы класс LogEntry следующим образом:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
@Entity(value="cappedLogsMorphia", cap=@CappedAt(count=5, value=4096))
public class LogEntry {
 
    private int logId;
 
    @Id
    private ObjectId id;
 
    public LogEntry(int logId) {
        this.logId = logId;
    }
 
    public int getLogId() {
        return logId;
    }
 
    public void setLogId(int logId) {
        this.logId = logId;
    }
}

Мы можем видеть, что этот класс аннотирован @Entity указывающим, что коллекция должна быть ограничена максимум 5 документами и размером 4096 байт.

При использовании Morphia ограниченная коллекция создается во время запуска путем вызова .ensureCaps() в Datastore .ensureCaps() как показано ниже.

1
2
3
4
5
6
7
8
MongoClient mongoClient = new MongoClient(new MongoClientURI("mongodb://localhost"));
DB db = mongoClient.getDB("test");
 
Morphia morphia = new Morphia();
morphia.map(LogEntry.class);
 
Datastore datastore = morphia.createDatastore(mongoClient, "test");
datastore.ensureCaps();

Опять же, как и прежде, мы можем вставить 8 документов в коллекцию, чтобы убедиться, что хранятся только последние 5.

1
2
3
4
for (int i = 0; i < 8; i++) {
    LogEntry logEntry = new LogEntry(i);
    datastore.save(logEntry);
}
1
2
3
4
5
6
> db.cappedLogsMorphia.find()
{ "_id" : ObjectId("54a1ce9da82629642c64f5d9"), "className" : "com.davidsalter.cappedcollection.LogEntry", "logId" : 3 }
{ "_id" : ObjectId("54a1ce9da82629642c64f5da"), "className" : "com.davidsalter.cappedcollection.LogEntry", "logId" : 4 }
{ "_id" : ObjectId("54a1ce9da82629642c64f5db"), "className" : "com.davidsalter.cappedcollection.LogEntry", "logId" : 5 }
{ "_id" : ObjectId("54a1ce9da82629642c64f5dc"), "className" : "com.davidsalter.cappedcollection.LogEntry", "logId" : 6 }
{ "_id" : ObjectId("54a1ce9da82629642c64f5dd"), "className" : "com.davidsalter.cappedcollection.LogEntry", "logId" : 7 }

Проверка статуса коллекции

.stats() ограниченную коллекцию в MongoDB, мы можем проверить ее состояние, выполнив метод .stats() для коллекции из интерактивной оболочки Mongo DB.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
> db.cappedLogsJavaDriver.stats()
{
    "ns" : "test.cappedLogsJavaDriver",
    "count" : 5,
    "size" : 180,
    "avgObjSize" : 36,
    "storageSize" : 4096,
    "numExtents" : 1,
    "nindexes" : 1,
    "lastExtentSize" : 4096,
    "paddingFactor" : 1,
    "systemFlags" : 1,
    "userFlags" : 0,
    "totalIndexSize" : 8176,
    "indexSizes" : {
        "_id_" : 8176
    },
    "capped" : true,
    "max" : 5,
    "ok" : 1
}

Здесь мы видим, что коллекция действительно ограничена («capped» = true) и что максимальное количество записей в коллекции равно 5 («max» = 5).

  • Исходный код примеров, используемых в этом посте, можно найти на GitHub .