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...');
});
Çö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...');
});