2015-05-22 2 views
2

Я просто играл вокруг концепций sailsjs, тогда я узнал, что мы не можем использовать автоматические приращения в парусах, если мы используем mongodb в качестве нашей базы данных. Я не могу использовать автоматические приращения даже для атрибутов не первичного ключа. Существуют ли специальные методы для использования операций автоматического приращения для атрибута, который не является первичным ключом? Заранее спасибоКак использовать auto increment в sails-mongo

ответ

7

Если ватерлиния не поддерживает его автоматически, это то, что кажется, вы можете сделать это в beforeCreatelifecycle callback ватерлинии. Он не зависит от любого адаптера базы данных.

Я бы порекомендовал вам взглянуть на то, как обратные вызовы жизненного цикла работают для четкого понимания. Рабочий процесс будет похож на следующий. Перед созданием любой записи вы проверите количество записей Model. Затем обновите поле x записей, которые будут созданы, как еще один найденный счетчик и передайте баттон.

beforeCreate: function(obj, next){ 
    Model.count().exec(function(err, cnt){ 
     if(err) next(err); 
     else{ 
      obj['x'] = cnt + 1; 
      next(null); 
     } 
    }) 
} 

Подсчет записей не является идеальным способом. Вы можете изменить способ, которым вы хотите найти значение автоинкрементного значения. Цель этого примера - дать вам представление о том, как это можно сделать. Это не точная альтернатива автоинкремента, но это эффективный обходной путь, я думаю. Надеюсь, это поможет вам.

+0

Прохладный решение! Что-то странное, но оно работает и легко решает проблему! Благодаря! –

+1

Где находится «Модель» var? – throrin19

+0

Хотя рекомендация beforeCreate звучит, использование метода count() не выполняется, потому что (a) значения obj ['x'] могут не совпадать с подсчетом, (b) если записи удаляются, значения будут сброшены и все записи должны быть обновлены, чтобы быть точными. Лучший способ: выполнить поиск() и отсортировать результаты на основе целочисленного столбца, выбрать первый результат, а затем увеличить его! – Joshua

7

Существуют различные стратегии, как вы можете создавать автоматические последовательности инкремента с монго. Вы можете найти общую информацию в официальной документации http://docs.mongodb.org/manual/tutorial/create-an-auto-incrementing-field/

Ниже приведена адаптация первого подхода к ватерлинии sails.js, в котором используется счетчик сбора. Сначала вам нужно создать модель последовательности и реализовать следующий метод.

module.exports = { 
    attributes : { 
     num : { 
      type : "integer" 
     }, 
    }, 

    next : function (id, cb) { 

     Sequence.native(function (err, col) { 

      col.findAndModify(
       { _id: id }, 
       [['_id', 'asc']], 
       {$inc: { num : 1 }}, 
       { new: true, upsert : true} 
       , function(err, data) { 

        cb(err, data.value.num); 
       }); 

     }); 

    }, 
}; 

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

И тогда вы можете просто вызвать метод Sequence.next() в методе обратного вызова метода beforeCreate вашей модели, чтобы получить следующее значение автоматического увеличения для нового документа коллекции.

// Model Order, for Example. 
module.exports = { 

    attributes: { 

     number: { 
      type: "integer" 
     }, 
     // other attributes 
    }, 

    // add auto increment value for "number" before create a document 
    beforeCreate : function (values, cb) { 

     // add seq number, use 
     Sequence.next("order", function(err, num) { 

      if (err) return cb(err); 

      values.number = num; 

      cb(); 
     }); 
    } 

    // your other methods ... 
}; 

Я знаю, что немного поздно, но я просто решил это для меня и хотел поделиться.

+2

Где находится 'Sequence' var? – throrin19

1

Для всех, кто интересуется реализацией с помощью Native in Sails, здесь это рабочий образец. В выборке предполагается, что у вас есть коллекция счетчиков:

Counters.native(function(err, collection) { 

     collection.findAndModify(
      {"_id": "order_id"}, // query 
      [['_id','asc']], // sort order 
      { "$inc": { "seq": 1 }}, // increments the seq 
      {"new": true}, // options 
      function(err, object) { 
       if (err){ 
        sails.log.debug("ERROR",err.message); // returns error if no matching object found 
       }else{ 
        sails.log.debug(object); 
       } 
      }); 
     });