LoopBack4 MongoDB自动递增自定义ID

时间:2019-01-11 10:36:20

标签: mongodb loopbackjs auto-increment

LoopBack本身对我来说是新的,我发现版本4与版本3太不同了。我的要求是,每次我创建REST端点的POST时,我都需要在mongoDB文档中有一个自定义的自动递增的id。类似于MySQL数据库中的运行ID。

我确实使用版本3的设置对此(auto-increment using loopback.js and MongoDB)和(https://gist.github.com/drmikecrowe/5a5568930bad567d4148aad75c94de5a)进行了检查,但是我没有找到合适的文档来在版本4上进行复制。

当前,我使用的是基本应用,并具有从环回4提供的开箱即用的REST实现。以下是我的模型的示例。

export class Test extends Entity {
  @property({
   type: 'string',
   id: true,
  })
  _id?: string;

  @property({
   type: 'number',
   generated: true,
   required: false
  })
  id: number;

  @property({
    type: 'string',
    required: true,
  })
  name: string;

  @property({
    type: 'boolean',
    required: true,
  })
  val: boolean;

  constructor(data?: Partial<Test>) {
    super(data);
  }
}

我的mongodb文档应如下所示:

{
  "_id" : ObjectId("5c373c1168d18c18c4382e00"),  
  "id"  : 1
  "name" : "aaaa",
  "val" : true
}
{
  "_id" : ObjectId("5c3869a55548141c0c27f298"),  
  "id"  : 2
  "name" : "bbbbb",
  "val" : false
}

4 个答案:

答案 0 :(得分:0)

您可以在此示例中执行类似的操作

@post('/characters', {
    responses: {
      '200': {
        description: 'Character model instance',
        content: {'application/json': {schema: {'x-ts-type': Character}}},
      },
    },
  })
  async create(@requestBody() character: Character): Promise<Character> {
    //add following lines
    let characterId = 1;
    while(await this.characterRepository.exists(characterId)){
      characterId ++;
    }
    character.id = characterId;

    //add above lines
    return await this.characterRepository.create(character);
  }

您可能已经注意到了自动递增ID功能。当您多次调用post API(将ID留空)时,ID每次都会增加1。内存数据库支持此功能。但是我们在这个项目中使用的是MongoDB。如果我们想拥有该功能,则需要以编程方式进行。

有关更多信息,请点击以下链接 https://strongloop.com/strongblog/building-online-game-with-loopback-4-pt1/

请参阅API Explorer标题上方的部分 或找到“自动增量ID”,您将被带到该段

希望这会有所帮助,如果还有其他查询,请写信给我。 谢谢

答案 1 :(得分:0)

我还在玩Mongo,它可以为您自动生成ID。

具体来说,当您使用lb4模型创建模型时,选择“实体”,然后系统会提示您:

  @property({
    type: 'string',
    id: true,
    generated: true,
  })
  id?: string;

这将使用以下属性生成您的模型:

? What kind of controller would you like to generate? REST Controller with CRUD functions
? What is the name of the model to use with this CRUD repository? Person
? What is the name of your CRUD repository? PersonRepository
? What is the name of ID property? id
? What is the type of your ID? string
? Is the id omitted when creating a new instance? Yes
? What is the base HTTP path name of the CRUD operations? /persons

太好了。然后在创建CRUD控制器时:

a+bi

现在,点击端点时,创建POST不需要ID,但会为您返回ID。

答案 2 :(得分:0)

您可以在此示例中执行类似的操作

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;

希望这会有所帮助,如果还有其他代码,请给我写信。谢谢

答案 3 :(得分:0)

此类从DefaultCrudRepository类继承,并且重写create方法。该方法使用“ Counters”集合来保存当前数据类的最后一个ID(this.entityClass.name)。 findAndModify方法将防止创建重复的id值。

import {DefaultCrudRepository, Entity, DataObject, Options} from '@loopback/repository';

export class MongoAutoIncIdRepository<T extends Entity, ID, Relations extends object = {}> extends DefaultCrudRepository<T, ID, Relations> {

  public async create(entity: DataObject<T>, options?: Options): Promise<T> {
    if (!this.dataSource.connected) {
      await this.dataSource.connect()
    }
    
    let mongoConnector = this.dataSource.connector!

    let collection = mongoConnector.db.collection('Counters')

    let result = await collection.findAndModify(
      {
        collection: this.entityClass.name
      },
      [['_id', 'asc']],
      {
        $inc: {value: 1}
      },
      {
        upsert: true,
        new: true
      })

    console.log(result)
    // @ts-ignore
    entity.id = result.value.value
    return super.create(entity, options)
  }

}

易于使用。如果需要自动递增,则不是从DefaultCrudRepository,而是从MongoAutoIncIdRepository继承存储库。然后,当调用create方法时,id会自动增加1。