使用knex.js在数组中插入多个数据时检查数据是否存在

问题描述

现在,我先插入产品,然后在数组中插入多个产品标签
但是产品标签将是重复的,而不会验证标签是否存在。

插入标签后如何检查标签是否存在?

这是我使用的代码

let product = {
  product: {
    name: 'techtech',tagline: '描述',thumbnail: 'images/products/techtech/thumbnail.png'
  },tags: [
    { name: 'Android',slug: 'android' },{ name: 'MacOS',slug: 'macos' },{ name: 'Windows',slug: 'windows' },{ name: 'Linux',slug: 'linux' }
  ],links: [ { url: 'techtech.cc' } ],covers: [
    { url: 'images/products/techtech/cover_0.png',index: 0 },{ url: 'images/products/techtech/cover_1.png',index: 1 }
  ]
}


 // insert product
return db.transaction(trx => {
  return trx('products')
  .insert(product.product)
  .returning('id')
  // insert product_tags
  .then(productIDs => {
    return trx(productTags)
    .insert(product.tags)
    .returning('id')
    // insert product_producttag_mapping
    .then(productTagIDs => {
      let productTags = productTagIDs.map((productTagID) => { 
        let productTag = {
          product_id: productID,producttag_id: productTagID
        }
        return productTag;
      });
      return trx('product_producttag_mapping')
      .insert(productTags)
      .returning('id')      
    })   
  })

解决方法

请注意,插入产品时,变量为productIDs,但是您正在使用productTag创建productId。您可能要添加const productId = productIds[0]

创建productTag时,还需要使用.id,如下所示。因为knex会返回具有该属性的对象。

    let productTag = {
      product_id: productID.id,producttag_id: productTagID.id
    }

但是您的实际问题是:如何使标签名称唯一?这会在插入时给您一个不错的错误。没有事务,您可以忽略该错误。 Postgres和Mysql具有不错的功能ON CONFLICT DO NOTHING。我不确定数据库在检测到重复项时是否会返回现有ID。因此,我认为您不会无所事事地阅读现有标签。通过他们的名字找到他们。在该列上有一个索引,应该是合理的快速。

专业提示:使用async/await重写代码时,小错误变得更加明显,您可以避免回调地狱。您不太可能会避免额外的查询。