使用Loopback.js和MongoDB实现自增ID

3
我希望您能够使用Loopback自动增加MongoDB文档数量。我在Mongo中创建了一个函数。
 function getNextSequence(name) {
   var ret = db.counters.findAndModify(
          {
            query: { _id: name },
            update: { $inc: { seq: 1 } },
            new: true
          }
   );

   return ret.seq;
}


db.tweet.insert(
{
   "_id" : getNextSequence("userid"),
  "content": "test",
  "date": "1",
  "ownerUsername": "1",
  "ownerId": "1"
}
)

它在mongo shell中运行正常。

但是当我使用loopback.js浏览器(http://localhost:3000/explorer/)进行插入时,它不起作用。显示400错误(SytaxError)代码。

我不能在loopback rest API中使用mongo函数吗?

我认为问题在于这行中的引号 getNextSequence("userid"),

enter image description here


你尝试过“保存前”解决方案吗? - Al Kafri Firas
4个回答

5
创建一个名为counters的集合,其属性包括valuecollection
{
  "name": "counters",
  "base": "PersistedModel",
  "idInjection": true,
  "options": {
    "validateUpsert": true
  },
  "properties": {
      "type": "number",
      "collection": "string"

  },
  "validations": [],
  "relations": {},
  "acls": [
    {
      "accessType": "*",
      "principalType": "ROLE",
      "principalId": "$everyone",
      "permission": "ALLOW"
    }
  ],
  "methods": []
}

假设您的自增集合名称为 tweets
将此值插入到 counters 中。
{
  "value" : 0, 
  "collection" : "tweet"
}

现在是 common/models/tweet.js。
tweet.observe('before save', function (ctx, next) {

        var app = ctx.Model.app;

        //Apply this hooks for save operation only..
        if(ctx.isNewInstance){
            //suppose my datasource name is mongodb
            var mongoDb = app.dataSources.mongodb;
            var mongoConnector = app.dataSources.mongodb.connector;
            mongoConnector.collection("counters").findAndModify({collection: 'tweet'}, [['_id','asc']], {$inc: { value: 1 }}, {new: true}, function(err, sequence) {
                if(err) {
                    throw err;
                } else {
                    // Do what I need to do with new incremented value sequence.value
                    //Save the tweet id with autoincrement..
                    ctx.instance.id = sequence.value.value;

                    next();

                } //else
            });
        } //ctx.isNewInstance
        else{
            next(); 
        }
    }); //Observe before save..

2
我想为Robin的答案添加一个要点,您可以添加upsert:true,这样如果文档不存在,它就会自动创建。
tweet.observe('before save', function (ctx, next) {

    var app = ctx.Model.app;

    //Apply this hooks for save operation only..
    if(ctx.isNewInstance){
        //suppose my datasource name is mongodb
        var mongoDb = app.dataSources.mongodb;
        var mongoConnector = app.dataSources.mongodb.connector;
        mongoConnector.collection("counters").findAndModify({collection: 'tweet'}, [['_id','asc']], {$inc: { value: 1 }}, {new: true,upsert:true}, function(err, sequence) {
            if(err) {
                throw err;
            } else {
                // Do what I need to do with new incremented value sequence.value
                //Save the tweet id with autoincrement..
                ctx.instance.id = sequence.value.value;

                next();

            } //else
        });
    } //ctx.isNewInstance
    else{
        next(); 
    }
}); //Observe before save..

2
你可以像这个 for loopback 4 的例子一样做些什么。
let last_record = await this.testRepository.findOne({order: ['id DESC']});
if(last_record) invoice.id = last_record.id+1;

这将使用属性生成您的模型:
@property({
    type: 'number',
    id: true,
    default: 1,
    generated: false
  })
  id: number;

希望这能帮到你,如果还有其他代码需要,请写信给我。谢谢。

0

如果您想在Loopback方法中直接使用MongoDB运算符,您需要启用"allowExtendedOperators"选项,您可以在每个模型的基础上或在数据源级别上这样做(将应用于使用数据源的所有模型)。

datasources.json:

  "MongoDs": {
    "host": "127.0.0.1",
    "port": 27017,
    "url": "mongodb://localUser:MYPASSWORD!@127.0.0.1:27017/test-database",
    "database": "test-database",
    "password": "MYPASSWORD!",
    "name": "MongoDs",
    "user": "localUser",
    "useNewUrlParser": true,
    "connector": "mongodb",
    "allowExtendedOperators": true
  },


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接