【问题标题】:LoopBack4 MongoDB Auto Increment custom IDLoopBack4 MongoDB 自动增量自定义 ID
【发布时间】:2019-06-06 06:33:01
【问题描述】:

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
}

【问题讨论】:

    标签: mongodb loopbackjs auto-increment


    【解决方案1】:

    你可以在这个例子中做类似的事情

    @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”,您将被带到该段

    希望这会有所帮助,如果有任何其他疑问,请写信给我。 谢谢

    【讨论】:

      【解决方案2】:

      我也在玩 Mongo,它可以为你自动生成你的 id。

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

      Let's add a property to Participant
      Enter an empty property name when done
      
      ? Enter the property name: id
      ? Property type: string
      ? Is id the ID property? Yes
      ? Is id generated automatically? Yes
      

      这将生成带有属性的模型:

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

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

      ? 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
      

      现在,当访问您的端点时,创建 POST 不需要 ID,但会为您返回一个。

      【讨论】:

        【解决方案3】:

        你可以在这个例子中做类似的事情

        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;
        

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

        【讨论】:

          【解决方案4】:

          该类继承自 DefaultCrudRepository 类并覆盖 create 方法。该方法使用“Counters”集合来保存当前数据类(this.entityClass.name)的最后一个 id。 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。

          【讨论】:

          • 虽然这可能是很好的代码,但这并不能解释任何事情。请添加一些解释为什么它有效。
          • 添加说明
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-06-22
          • 2014-06-28
          • 2017-03-18
          • 1970-01-01
          • 2020-07-19
          • 2017-04-20
          • 1970-01-01
          相关资源
          最近更新 更多