MongoDB Otomatik ID arttırma (auto increment)

Merhabalar, index.html’deki formdan gelen veriyi DB’ye yazarken her yeni veri için 1’den başlayarak artan bir ID değeri aldırmaya çalışıyorum.
NodeJS ile MongoDB’ye yaptığım gönderilerim için bir ID değerinin her yeni gönderi için otomatik artan değer almasını istiyorum. Önce internetten yardım almadan kendim basit bir algoritma ile bu sorunu çözebileceğimi düşündüm. Algoritma basitti:
1- Son girdiyi bul
2- ID değerini oku bir arttır ve bir değişkene ata
3- yeniID değerini veri tabanına yazılacak ID değeri olarak ekleyerek gönder.
4- Son girdi bulunamamış ve hata vermişse yeniID değerini 1 döndür.

Bu kadar basit görünen algoritmayı kodlara dökmek benim için imkansız oldu çünkü NodeJS’in asenkron yapısı içinde çalışan bir kod yazamadım. Sonra başkaları ne yapmış diye araştırmaya başladım.

bu başlık altındaki kodları kendi sistemime adapte etmek istediğimde de başaramadım. İster pür MongoDB kütüphanesiyle ister Mongoose ile yazılmış olsun bana bir çözüm lazım.

const express = require('express');

const app = express();

const path = require('path');

const mngs = require('mongoose');

const bodyparser = require('body-parser');

app.use('/public', express.static(path.join(__dirname, 'public'))); //express.static herkese açık klasörü belirler

app.use(bodyparser.urlencoded({extended:false})); // URL olarak gelen requestleri parçalayarak kullanımını kolaylaştırır

app.use(bodyparser.json({extended:false})); // JSON olarak gelen requestleri parçalayarak kullanımını kolaylaştırır

//mongo ile bağlantı kuruluyor "mongodb://127.0.0.1:27017" ifadesi standarttır. "/chatDB" ise oluşturduğumuz DB ismi

mngs.connect('mongodb://127.0.0.1:27017/chatDB',{ useNewUrlParser: true, useUnifiedTopology: true }, function(err,data){

  if (err){

      console.log('sunucu bağlantı hatası:'+err)

  }else{

  console.log('DB bağlandı...')}

});

//otomatik arttırma şeması

const otoSchema = mngs.Schema;

let DBsema2 = new otoSchema(

  {

    _id: {type: String, required: true},

    seq: { type: Number, default: 0 }

  },

  {

    collection:'otoartis'

  }

);

let otoSema = mngs.model('otoSema', DBsema2);

/* /otoarttırma için ilk girdiyi manuel yapıyoruz.

otoSema.create({ _id: 1, seq: 1 }, function(err,result){

    if(err) throw err;

console.log('otoarttırma için ilk girdi oluşturuldu');

});

*/

//mongoose ile veri göndermek için önce veri tabanı şeması oluşturuyoruz, böylece giden veriler şema ile aynı yapıda DB'ye kaydolacak. "mesajlar" colection ismimizi gösterir

const Schema = mngs.Schema;

let DBsema = new Schema(

  {

  msgID:Number,

  mesaj:String,

  tarih:{type:Date, default:Date.now}

  },

  {

    collection:'mesajlar'

  }

);

let ChatSema = mngs.model('ChatSema', DBsema);

//chat şemasını msgID değerini otosema'nın "seq" değerine eşitliyoruz

DBsema.pre('save', function(next){

otoSema.findByIdAndUpdate({_id: 'msgID'}, {$inc: { seq: 1} }, {new: true, upsert: true}).then(function(gelenveriler){

    console.log("...count: "+JSON.stringify(gelenveriler));

    this.msgID=gelenveriler.seq;

    next();

}).catch(function(e){throw e});

});

//ana sayfa için index.html sayfasını gönderiyoruz

//Get metodu ile

app.get('/', function (req, res) {

    res.sendFile(__dirname + '/index2.html');

});

//Post ile gelen veriyi DB'ye yazma

app.post('/', function (req, res) {

    res.sendFile(__dirname + '/index2.html');

    console.log('post geldi');

    var varmesaj= req.body.mesaj;

    ChatSema.create({mesaj:varmesaj}, function(err,result){

        if(err) throw err;

    console.log('mesaj DBye yazıldı');

    });

});

//sunucu çalışmaya başlar

app.listen(9999, function () {

    console.log('Sunucu çalışıyor...');

  });

Sorun nerede?

2 Beğeni

Çözümü aşağıdaki gibi buldum. Veritabanına her kayıt girilmeden önce idcek(varmesaj, veriyaz); fonksiyonunu kullanmam gerekecek ama şimdilik işimi görecek. Bunu otomatize etmek halâ benim için bir gizem konumunda. Aslında Schema.pre("save", ()=>{}) yapısı hakkında bir fikrim olsa o işi de çözeceğim ama şimdilik elimden gelen bu.

const express = require('express');
const app = express();
const path = require('path');
const mngs = require('mongoose');
const bodyparser = require('body-parser');
const { resolve } = require('dns');  //bunlar otomatik olarak geldi ben yazmadım nasıl geldiğine dair hiç bir fikrim yok :)
const { rejects } = require('assert');//bunlar otomatik olarak geldi ben yazmadım nasıl geldiğine dair hiç bir fikrim yok :)
const { callbackify } = require('util');//bunlar otomatik olarak geldi ben yazmadım nasıl geldiğine dair hiç bir fikrim yok :)

app.use('/public', express.static(path.join(__dirname, 'public'))); //express.static herkese açık klasörü belirler
app.use(bodyparser.urlencoded({extended:false})); // URL olarak gelen requestleri parçalayarak kullanımını kolaylaştırır
app.use(bodyparser.json({extended:false})); // JSON olarak gelen requestleri parçalayarak kullanımını kolaylaştırır

//mongo ile bağlantı kuruluyor "mongodb://127.0.0.1:27017" ifadesi standarttır. "/chatDB" ise oluşturduğumuz DB ismi
mngs.connect('mongodb://127.0.0.1:27017/chatDB',{ useNewUrlParser: true, useUnifiedTopology: true }, function(err,data){
  if (err){
      console.log('sunucu bağlantı hatası:'+err)
  }else{
  console.log('DB bağlandı...')}
});

//mongoose ile veri göndermek için önce veri tabanı şeması oluşturuyoruz, böylece giden veriler şema ile aynı yapıda DB'ye kaydolacak. "mesajlar" colection ismimizi gösterir
const Schema = mngs.Schema;
let DBsema = new Schema(
  {
  msgID:String, //Sabit artan bir ID değeri olarak bunu kullanacağım. mongoDB'nin kendi verdiği __id değerine dokunmayacağım. İşlemlerin sonunda hem birbirinden farklı __id değerlerimiz olacak hemde msgID adında sıralı artan özel bir IDmiz olacak.
  mesaj:String,
  tarih:{type:Date, default:Date.now}
  },
  {
    collection:'mesajlar'
  }
);
let ChatSema = mngs.model('ChatSema', DBsema);

//ana sayfa için index.html sayfasını gönderiyoruz
//Get metodu ile
app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index2.html');
});

//Post ile gelen veriyi DB'ye yazma
app.post('/', function (req, res) {
    res.sendFile(__dirname + '/index2.html');
    console.log('1-Post geldi');
    var varmesaj= req.body.mesaj;
    idcek(varmesaj, veriyaz); //gelen mesajı DB'ye yazmadan önce eski mesajın msgID'sini
});

function idcek(varmesaj, callback){
  ChatSema.find({},function(err,data){ //DB'deki verileri çekiyoruz
    if(err){
      console.log('hata aldık');
    }else{
      try{     //ilk veri girişinde DB'de veri bulunamayacağı için hata verecek biz de catch bölgesinde ilk ID'yi 1 vereceğiz
      console.log('2-DBdeki data sayısı:'+data.length);
      var son_veri_no= data.length-1
      var son_msgID= data[son_veri_no].msgID; //DB'deki son girilen verinin msgID değerini buluyoruz
      console.log('3-DBdeki son veriye ait msgID değeri:'+son_msgID);
      son_msgID++; //sıradaki mesajın msgID değeri olacağı için bir arttırıyoruz
      console.log('4-son mesajın IDsi 1 arttı:'+son_msgID);
      callback(varmesaj, son_msgID);     //Asenkron yapıdan etkilenmemek ve yazma işlemine bir sonraki adımda başlamak için Callback fonksiyonundan yararlanıyoruz
    }catch{     //ilk veri girişinde DB'de veri bulunamayacağı için hata verecek biz de catch bölgesinde ilk ID'yi 1 vereceğiz
      var son_msgID=1;
      callback(varmesaj, son_msgID);
    }};
  });
}

function veriyaz(varmesaj, gelenveri){ //bu fonksiyonu idcek()fonksiyonu çağırması için özel olarak tasarladık
  ChatSema.create({mesaj:varmesaj, msgID:gelenveri}, function(err, data){
    if (err)throw err;
    console.log("5-mesaj DBye yazıldı")
  });
}

//sunucu çalışmaya başlar
app.listen(9999, function () {
    console.log('Sunucu çalışıyor...');
  });