在我的项目中,有两个模型" UserProfile"和" UserAccount"有一种关系,前者"有一个"后来。 .json文件看起来像:
userprofile.json:
{
"name": "Userprofile",
"base": "PersistedModel",
//...
"properties": {
"userid": {
"type": "Number"
},
"phoneno": {
"type": "String"
}
},
//...
"relations": {
"userAccounts": {
"type": "hasOne",
"model": "UserAccount",
"foreignKey": "id",
"options": {
"validate": true,
"forceId": false
}
}
}
}
useraccount.json:
{
"name": "UserAccount",
"base": "User",
"idInjection": true,
"restrictResetPasswordTokenScope": true,
"emailVerificationRequired": true,
"properties": {},
"relations": {}
//...
}
模型在MariaDB中有相应的表。
现在的任务是" GET" UserProfile,其关键字与UserProfile.phoneno 或 UserAccount.email的任何一个字段匹配(是的,关键点是或)。在SQL术语中,即:
SELECT * FROM UserProfile INNER JOIN UserAccount
ON UserProfile.userid = UserAccount.id
WHERE UserProfile.phoneno LIKE '%keyword%'
OR UserAccount.email LIKE '%keyword%'
它应该是SQL中常见且简单的查询,但在LookBack中似乎变得很困难。我的实现是:
userprofile.js:
'use strict';
module.exports = function (Userprofile) {
Userprofile.remoteMethod('profileByEmailOrPhoneno', {
description: '...',
http: {path:'/profileByEmailOrPhoneno', verb: 'get'},
accepts: {arg: 'keyword', type: 'string', required: true},
returns: {arg: 'profile', type: 'array' }
})
Userprofile.profileByEmailOrPhoneno = function (keyword, cb) {
let filter = {
fields: {userid: true, nickname: true, phoneno: true},
include: {
relation: 'userAccounts',
scope: {
fields: {username: true, email: true}
}
},
where: {or: [
{phoneno: {like: `%${keyword}%`}},
{'userAccount.email': {like: `%${keyword}%`}}
]}
}
Userprofile.find(
filter,
function (err, records) {
if (err) console.log(err)
else cb(null, records)
}
)
}
};
我在StrongLoop API Explorer上测试了它,无论关键字是什么,它总是返回UserProfile中的所有记录。如果标准
{'userAccount.email': {like: `%${keyword}%`}}
删除了代码正常工作。我认为这个标准是错误的,所以LookBack忽略它并评估where部分是真的。我将其修改为:
{'email': {like: `%${keyword}%`}}
它仍然是错误的。
所以,我想知道如何正确命名关系模型的字段(例如,'电子邮件'),或者如何编写正确的过滤器。有人可以帮忙吗?我非常感谢它。 ^^
答案 0 :(得分:0)
Loopback中的 include 语句是一个left-outer-join,因此查询将始终返回所有Userprofile记录。有些人将拥有带有数组值的userAccounts,其他人则不会。您需要进一步过滤Userprofile记录。
此外,您需要将userAccoutns过滤器放在过滤器的范围语句中:
Userprofile.profileByEmailOrPhoneno = function (keyword, cb) {
let filter = {
fields: {userid: true, nickname: true, phoneno: true},
include: {
relation: 'userAccounts',
scope: {
fields: {username: true, email: true},
where: {'email':{'like': `%${keyword}%`}} // userAccounts filter goes here
}
},
where: {phoneno: {like: `%${keyword}%`}}
}
Userprofile.find(filter, function (err, records) {
if (err) console.log(err)
else {
// filter the records for those that have userAccounts
var filteredResults = records.filter(record =>
record.userAccounts &&
Array.isArray(record.userAccounts()) &&
record.userAccounts().length);
cb(null, filteredResults)
}
})
}