Как вы реализуете автоинкрементный первичный идентификатор в MongoDB? - PullRequest
9 голосов
/ 05 декабря 2010

Как и в MYSQL, я хочу увеличить ID.

Ответы [ 7 ]

18 голосов
/ 05 декабря 2010

Вам нужно будет использовать команду MongoDB findAndModify . С его помощью вы можете атомарно выделять и увеличивать поле .

db.seq.findAndModify({
  query: {"_id": "users"},
  update: {$inc: {"seq":1}},
  new: true
});

Это увеличит счетчик для коллекции users, которую можно затем добавить в документ перед вставкой. Поскольку он атомарный, вам не нужно беспокоиться о состоянии гонки, что приведет к конфликту идентификаторов.

Это не так легко, как флаг MySQL auto_increment, но у вас также обычно есть возможность указать свою собственную фабрику идентификаторов в вашем драйвере Mongo, чтобы вы могли реализовать фабрику, которая использует findAndModify для прозрачного увеличения и возврата идентификаторов, в результате гораздо более похожий на MySQL опыт.

Недостатком этого подхода является то, что, поскольку каждая вставка зависит от блокировки записи в вашей коллекции последовательностей, если вы делаете много записей, вы можете довольно быстро столкнуться с узкими местами. Если вы просто хотите гарантировать, что документы в коллекции отсортированы в порядке вставки, посмотрите на Ограниченные коллекции .

13 голосов
/ 05 декабря 2010

MongoDB предназначен для горизонтального масштабирования. В этом случае автоинкремент приведет к конфликтам идентификаторов. Вот почему идентификатор выглядит гораздо больше как guid / uuid.

2 голосов
/ 21 марта 2016

MongoDB предоставляет 2 способа автоматического увеличения _id (или пользовательский ключ) .

Коллекция счетчиков


Здесь нам нужно создать коллекцию, которая хранит максимальное количество ключей и увеличивает их на 1 каждый разкогда мы вызываем эту функцию.

1.ФУНКЦИЯ МАГАЗИНА

function getNextSequence(collectionName) {
   var ret = db.counters.findAndModify({
               query: { _id: collectionName },
               update: { $inc: { seq: 1 } },
               new: true,
               upsert: true
             });

   return ret.seq;
}

2.INSERT DOC

db.users.insert({
  _id: getNextSequence("USER"),
  name: "Nishchit."
})

Optimistic Loop


В этом шаблоне Optimistic Loop вычисляет увеличенное значение _id и пытается вставить документ с вычисленным значением _id.Если вставка прошла успешно, цикл заканчивается.В противном случае цикл будет повторять возможные значения _id до тех пор, пока вставка не будет успешной.

1.ФУНКЦИЯ МАГАЗИНА

function insertDocument(doc, targetCollection) {

    while (1) {

        var cursor = targetCollection.find( {}, { _id: 1 } ).sort( { _id: -1 } ).limit(1);

        var seq = cursor.hasNext() ? cursor.next()._id + 1 : 1;

        doc._id = seq;

        var results = targetCollection.insert(doc);

        if( results.hasWriteError() ) {
            if( results.writeError.code == 11000 /* dup key */ )
                continue;
            else
                print( "unexpected error inserting data: " + tojson( results ) );
        }

        break;
    }
}

2.INSERT DOC

var myCollection = db.USERS;

insertDocument(
   {
     name: "Nishchit Dhanani"
   },
   myCollection
);

Официальный документ от MongoDB .

1 голос
/ 31 декабря 2010

Если вы подозреваете, что ваши данные могут охватывать более одного сервера (то есть шарды), тогда используйте Деннис и используйте собственный ObjectId.

Если вы предпочитаете int / long id (выглядит лучше по URL), тогдаможно начать с наивной реализации генератора, используя findAndModify, как предложил Крис.Когда / если производительность / блокировка начинает вызывать проблемы, вы можете обновить свой генератор для реализации алгоритма Hi / Lo.Это приведет к гораздо меньшей нагрузке на коллекцию 'seq'.и практически устранить эту проблему.(генератор на стороне клиента использует «пул» и связывается с БД только тогда, когда у него больше нет свободных идентификаторов)

0 голосов
/ 18 декабря 2014

Я использую это - автоматическое увеличение mongoose

var mongoose = require('mongoose'),
    Schema = mongoose.Schema,
    autoIncrement = require('mongoose-auto-increment');

var connection = mongoose.createConnection("mongodb://localhost/myDatabase");

autoIncrement.initialize(connection);

var bookSchema = new Schema({
    author: { type: Schema.Types.ObjectId, ref: 'Author' },
    title: String,
    genre: String,
    publishDate: Date
});

bookSchema.plugin(autoIncrement.plugin, 'Book');
var Book = connection.model('Book', bookSchema);
0 голосов
/ 17 октября 2013

@ TIMEX: проверьте, может ли вам помочь приведенная ниже ссылка, если вы искали порядковый номер, а не ID (coz ID зарезервирован mongo)

http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/#auto-increment-counters-collection

@ Деннис БертонАвто приращение, если пользователь не вызовет столкновения?я чувствую, следовательно, mongo db использует свой собственный _Id, чтобы избежать коллизий, но если пользователь желает иметь столбец в качестве последовательности выполнения, он может использовать его

0 голосов
/ 06 декабря 2010

Хотя автоматическое увеличение не поддерживается, вы можете легко реализовать собственный маленький класс для выдачи добавочных значений.

Мне нужна была эта функция, поэтому я написал небольшой класс на php. Я написал об этом в своем блоге, здесь посмотрите здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...