programing

Mongoose는 Mongodb의 findAndModify 메서드를 지원합니까?

closeapi 2023. 7. 15. 10:08
반응형

Mongoose는 Mongodb의 findAndModify 메서드를 지원합니까?

Mongoose를 사용하여 findAndModify를 사용하여 필드를 원자적으로 증가시키고 싶습니다.

그러나 아래 코드는 "TypeError: Object # have no method 'findAndModify'" 오류를 발생시킵니다.

// defining schema for the "counters" table
var tableSchema = new Schema({
    _id: String,
    next: Number        
});

// creating table object for the counters table
var counters_table = mongoose.model('counters', tableSchema);
var tableObj = new counters_table();    

// increment the "next" field on the table object
var query = {_id: 'messagetransaction'};
var update = {'$inc': {next: 1}};
var ret = tableObj.findAndModify(query, [], update, true, true, function(err) {
     if (err) { 
         throw err;
     }
     else { 
         console.log("updated!");
     }
});

이 기능은 문서화되어 있지 않지만(읽기: 전혀) 소스 코드를 읽어본 후 다음과 같은 해결책을 생각해냈습니다.

컬렉션 스키마를 만듭니다.

var Counters = new Schema({
  _id: String,
  next: Number     
});

모델 컬렉션의 findAndModify 메서드를 표시할 정적 메서드를 스키마에 만듭니다.

Counters.statics.findAndModify = function (query, sort, doc, options, callback) {
  return this.collection.findAndModify(query, sort, doc, options, callback);
};

모델을 만듭니다.

var Counter = mongoose.model('counters', Counters);

찾아서 수정하세요!

Counter.findAndModify({ _id: 'messagetransaction' }, [], { $inc: { next: 1 } }, {}, function (err, counter) {
  if (err) throw err;
  console.log('updated, counter is ' + counter.next);
});

보너스

Counters.statics.increment = function (counter, callback) {
  return this.collection.findAndModify({ _id: counter }, [], { $inc: { next: 1 } }, callback);
};

Counter.increment('messagetransaction', callback);

이름은 약간 다르지만 현재 Mongoose 3.x에서 완전히 지원됩니다.

http://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate

http://mongoosejs.com/docs/api.html#model_Model.findByIdAndUpdate

http://mongoosejs.com/docs/api.html#model_Model.findOneAndRemove

http://mongoosejs.com/docs/api.html#model_Model.findByIdAndRemove

Mongoose 3.x에 대한 작업 버전 증분

var mongoose = require('mongoose');

var CounterSchema = new mongoose.Schema({
    _id: String,
    next: {type: Number, default: 1}
});

CounterSchema.statics.increment = function (counter, callback) {
    return this.findByIdAndUpdate(counter, { $inc: { next: 1 } }, {new: true, upsert: true, select: {next: 1}}, callback);
};

다음과 같은 방법을 사용합니다.

Counter.increment('photo', function (err, result) {
    if (err) {
        console.error('Counter on photo save error: ' + err); return;
    }
    photo.cid = result.next;
    photo.save();
});

도움이 되는 사람이 왔으면 좋겠습니다.

버전 3에서 mongoose findOneAndUpdate 메서드는 mongodb의 findAndModify 작업을 표시합니다.다음과 같이 작동합니다.

var query = { name: 'Sprinkls' };
var update = { name: 'Sprinkles' };
var options = { new: false };
Cat.findOneAndUpdate(query, update, options, function (err, cat) {
  if (err) ..
  render('cat', cat);
});

자세한 내용은 http://aaronheckmann.tumblr.com/post/48943524629/mongoose-v3-part-2-findandmodify 에서 확인할 수 있습니다.

많은 답들이 있지만 저는 이 간단한 해결책을 찾습니다.

Counter.findByIdAndUpdate(ID, {$inc: {next:1}}, function (err, data) {


});

찾고 수정했습니다.

  • 카운터를 다시 설정합니다(없는 경우 카운터 만들기 및 초기화).
  • 카운터 증가
  • 증분 값을 사용하여 콜백

다음 코드를 사용하여 단일 DB 왕복에서.

var Counters = new Schema({
  _id:String, // the schema name
  count: Number
});

Counters.statics.findAndModify = function (query, sort, doc, options, callback) {
    return this.collection.findAndModify(query, sort, doc, options, callback);
};

var Counter = mongoose.model('Counter', Counters);

/**
 * Increments the counter associated with the given schema name.
 * @param {string} schemaName The name of the schema for which to
 *   increment the associated counter.
 * @param {function(err, count)} The callback called with the updated
 *   count (a Number).
 */
function incrementCounter(schemaName, callback){
  Counter.findAndModify({ _id: schemaName }, [], 
    { $inc: { count: 1 } }, {"new":true, upsert:true}, function (err, result) {
      if (err)
        callback(err);
      else
        callback(null, result.count);
  });
}

즐기세요! - 커란

@furf로부터 위의 답변을 받아, 이것은 나의.promised솔루션:

// eslint-disable-next-line func-names
localeTypesSchema.statics.findAndModify = function (query, sort, update, opts, callback) {
    const cb = callback || (() => { });
    try {
        const result = this.collection.findAndModify(query || {}, sort || [], update || {}, opts);
        cb(null, result);
        return Promise.resolve(result);
    } catch (err) {
        cb(err);
        return Promise.reject(err);
    }
};

http://www.mongodb.org/display/DOCS/findAndModify+Command 하단에 표시된 직접 명령 스타일을 사용하는 것이 좋습니다.mongoose에 익숙하지 않아서 명령을 실행하는 방법을 알 수 없지만 모든 드라이버가 명령을 실행하는 방법을 제공합니다.몽구스가 그렇지 않다면, http://www.mongodb.org/display/DOCS/Commands 상단에 설명된 스타일을 사용하여 직접 할 수 있습니다.

그렇긴 하지만, 당신은 당신이 정말로 필요로 하는 것을 확인해야 합니다.findAndModify그 밖에update당신이 해야 할 일을 하지 않을 겁니다무엇을 보기 위해updatehttp://www.mongodb.org/display/DOCS/Updating 을 살펴볼 수 있습니다.

쿼리에서 objectId를 사용하면 mongoDB가 문서를 찾을 수 없다는 furf 답변에 추가합니다.mongoose 계층은 라우팅 매개 변수에서 얻은 16진수 문자열 개체 ID를 적절한 개체 ID로 변환하는 작업을 수행합니다.

이 문제를 해결하려면 다음을 수행해야 합니다.

var ObjectID = require('mongodb').ObjectID;


var itemId = req.params.itemId;
var objectId = ObjectID.createFromHexString(itemId);
Item.findAndModify({_id: objectId},

언급URL : https://stackoverflow.com/questions/7334390/does-mongoose-support-the-mongodb-findandmodify-method

반응형