1***@qq.com
1***@qq.com
  • 发布:2025-10-25 00:10
  • 更新:2025-10-25 16:48
  • 阅读:91

【报Bug】正常查询无法成功,报错e.split is not function

分类:uniCloud

产品分类: uniCloud/App

示例代码:
const res = await db.collection(  
  db.collection('xz_order_shopping').where({  
  'snapshot.store._id': storeId,  
  createDate: _.and(_.gt(currentStart), _.lt(currentEnd)),  
  is_late_payments: true,  
  is_canceled: _.neq(true)  
}).getTemp(),  
db.collection('xz_order').where({  
  presetType: 'shopping',  
  createDate: _.and(_.gt(currentStart - 1000 * 60), _.lt(currentEnd + 1000 * 60)),  
  is_offline_paid: _.neq(true),  
  paid: _.neq(true)  
}).getTemp(),  
).where({  
  orderID: _.size(1)  
}).foreighKey('xz_order_shopping.orderID').count();

操作步骤:

运行查询语句

预期结果:

正常查询

实际结果:

{err: Error: e.split is not a function
at _construct (http://127.0.0.1:46530/appservice/common/vendor…}(env: Windows,mp,1.06.2504030; lib: 3.10.3)

bug描述:

客户端数据库联表查询报错,

2025-10-25 00:10 负责人:无 分享
已邀请:
青衫行者

青衫行者

这段 uniCloud JQL 联表查询代码存在一些明显问题和潜在的逻辑问题


⚠️ 语法和结构问题

  • db.collection() 括号使用错误:
    在进行联表查询时,第一个参数应是主表名(字符串),或者像您这样直接在第一个位置传入一个 getTemp() 子句
    您的代码在最外层的 db.collection() 中,传递了两个独立的 db.collection().where().getTemp() 子句作为参数:

    const res = await db.collection(  
      db.collection('xz_order_shopping').where({...}).getTemp(), // 子句 1  
      db.collection('xz_order').where({...}).getTemp(),          // 子句 2  
    ).where({...}) // ...  

    正确写法通常是:

    1. 直接关联多个表名(已不推荐):db.collection('table1', 'table2', 'table3').where({...})
    2. 使用 getTemp() 联表(推荐)要么在一个 db.collection() 中传入主表名,然后用 foreignKey 关联其他表(可能是用 getTemp() 定义的临时表);要么像您尝试的,直接将所有需要联表的临时表子句作为参数传入 db.collection()

    如果使用您当前的形式(传入多个 getTemp() 子句),正确的语法应该是将它们放在一个数组中,或者用逗号隔开作为多个参数(虽然 JQL 文档中更常见的是传入一个临时表名或一个临时表子句)。

    ⚠️ 根据 uniCloud 官方 JQL 文档中 getTemp 的用法,您的结构似乎是想进行 多表联查,但如果您的意图是只关联这两个临时表,参数的传递方式可能需要调整,例如:

    const res = await db.collection(  
      db.collection('xz_order_shopping').where({...}).getTemp(),   
      db.collection('xz_order').where({...}).getTemp()  
    ).where({...}) //...  
    // 或  
    const res = await db.collection('xz_order_shopping', 'xz_order')   
      .where({ ... }) // ...  

    最合理的猜测是您想在主表 'xz_order_shopping' 的查询结果上,通过 foreignKey 关联 'xz_order' 的临时表结果。

    如果是这样,您的联表查询结构应为:

    const res = await db.collection(  
        db.collection('xz_order_shopping').where({   
            //... xz_order_shopping 的条件  
        }).getTemp('temp_shopping'), // 给第一个临时表命名  
        db.collection('xz_order').where({   
            //... xz_order 的条件  
        }).getTemp('temp_order') // 给第二个临时表命名  
    )  
    .foreignKey('temp_shopping.orderID', 'temp_order.orderID') // 明确关联字段  
    .where({  
        //... 联表后的条件  
    })   
    .count()  

    但您后续使用了 foreighKey('xz_order_shopping.orderID')这表明您的意图更可能是以其中一个表为主表,关联另一个表。

  • foreighKey 拼写错误:
    函数名拼写错误,应为 foreignKey,而不是 foreighKey

  • foreignKey 使用方式不明确:
    您只传递了一个参数 'xz_order_shopping.orderID'。通常 foreignKey 是用来建立主表(或左表)和被关联表(或右表)之间关联关系的。
    当您直接传入两个 getTemp() 子句进行联表时,foreignKey 应该指定两个表的关联字段,例如:
    foreignKey('temp_shopping.orderID', 'temp_order.orderID')
    如果您只传入一个字段名,JQL 会根据约定当前上下文来尝试关联,但在您这种复杂的 getTemp() 结构下,很容易出错或不符合预期。


? 潜在逻辑问题

  • orderID: _.size(1) 的意义:
    这通常意味着查询结果中 orderID 字段的数组大小为 1。然而,orderID 字段在一个订单表中通常是字符串或数字,而不是数组。如果您确认 orderID 在您的表结构中是一个包含单个元素的数组,则没问题;否则,这个条件会过滤掉所有非数组或数组长度不为 1 的记录,这很可能不是您的本意。
  • 第二个临时表的时间查询:
    xz_ordercreateDate 条件是:
    createDate: _.and(_.gt(currentStart - 1000 * 60), _.lt(currentEnd + 1000 * 60))
    这比第一个表的查询范围扩大了前后 1 分钟。虽然不一定是错的,但如果目的是精确匹配,应该保持一致。如果这个表是用来找匹配订单的,稍微放宽时间范围也说得通,但需要确认逻辑是否严谨
  • 表别名:
    在联表查询中,使用 getTemp() 时最好给临时表取一个别名(如 getTemp('temp1')),这样在 foreignKey 和后续的 fieldwhere 中引用字段时会更清晰和准确。

✅ 总结和修改建议

假设您的意图是:找到所有符合条件的 xz_order_shopping 订单,并关联上符合条件的 xz_order 订单,然后统计总数。

这是修正拼写和结构后的示例,并假设您想使用联表查询

const res = await db.collection(  
  db.collection('xz_order_shopping').where({  
    'snapshot.store._id': storeId,  
    createDate: _.and(_.gt(currentStart), _.lt(currentEnd)),  
    is_late_payments: true,  
    is_canceled: _.neq(true)  
  }).getTemp('shoppingOrders'), // <--- 加上别名  
  db.collection('xz_order').where({  
    presetType: 'shopping',  
    // 假设时间范围是为了多找一些可能的匹配项,所以保留  
    createDate: _.and(_.gt(currentStart - 1000 * 60), _.lt(currentEnd + 1000 * 60)),   
    is_offline_paid: _.neq(true),  
    paid: _.neq(true)  
  }).getTemp('mainOrders') // <--- 加上别名  
)  
// 修正 foreignKey 拼写,明确关联两个临时表的 orderID 字段  
.foreignKey('shoppingOrders.orderID', 'mainOrders.orderID')   
// 修正 orderID: _.size(1) 的逻辑。如果想查询 orderID 存在,通常不需要这一步,  
// 联表成功意味着字段存在。如果确实想对联表后的结果加条件,可以保留或修改  
.where({  
  'shoppingOrders.orderID': _.exists, // 示例:检查 shoppingOrders 中的 orderID 是否存在  
  // 如果你的本意就是查询 orderID 字段是数组且长度为 1,则保留 'orderID': _.size(1)   
})  
.count();

注意: 联表查询的复杂性较高,建议您先分步查询,确保每个 getTemp() 子句返回的结果正确,再进行联表和 foreignKey 的调试。

要回复问题请先登录注册