如何在环回中使用过滤器获得订单“2”<“10”?
how can I get order '2' < '10' with filter in loopback?
我的数据像 ['2', '13', '13A', '14-1']
,我怎样才能得到 filter
的正确顺序?谢谢大家。
IIUC,您将数字(2
、10
等)作为字符串('2'
、'10'
等)存储在数据库中。
LoopBack 依赖于数据库来执行排序(排序)。
这里有一些尝试:
修改您的模型定义以将 属性 存储为 number
。 LoopBack 很聪明,会在将用户(REST API 客户端)提供的字符串值存储到数据库之前将其强制转换为数字。这将是我的首选解决方案,因为它不需要您的应用程序中的任何复杂代码并保持性能。
根据您使用的数据库,可以将其配置为将字符串值视为数字进行排序。这不是特定于 LoopBack 的,我真的帮不了你。
作为最后的手段,您可以对内存中的记录进行排序,当数据库不支持基于位置的查询时,LoopBack 已经这样做了。这个想法是告诉数据库 return 所有 符合 filter
条件的记录,然后应用 order
、limit
、skip
和 Node.js 进程中的其他选项。请注意,这会严重影响性能,并且仅适用于合理大小的数据。
至于第三个选项:在实现方面,您需要覆盖模型中的 find
方法 class。
// common/models/my-model.js
module.exports = function(MyModel) {
MyModel.on('modelRemoted', () => {
MyModel._findRaw = MyModel.find;
MyModel.find = findWithCustomSort;
});
}
function findWithCustomSort(filter, options, cb) {
if (!cb) {
if (typeof options === 'function') {
cb = options;
options = undefined;
} else if (!options && typeof filter === 'function') {
cb = filter;
filter = undefined;
}
}
const dbFilter = {
where: filter.where,
include: filter.include,
fields: filter.fields,
};
if (cb) {
this._findRaw(dbFilter, options, (err, found) => {
if (err) return cb(err);
else cb(null, sortResults(filter, found))
});
} else {
return this._findRaw(dbFilter, options)
.then(found => sortResults(filter, found));
}
}
function sortResults(filter, data) {
// implement your sorting rules, don't forget about "limit", "skip", etc.
}
更新
Is there a way to use sql for query in custom method?
是的,您可以使用 MyModel.dataSource.connector.execute
函数执行任何 SQL,请参阅 Executing native SQL。但有一个问题 - 此方法是基于回调的,您不能使用 Promise API 或 async/await.
const idValue = 1;
MyModel.dataSource.connector.execute(
'SELECT * FROM MyModel WHERE id=?',
[idValue]
(err, results) => {
if (err) console.error('query failed', err);
else console.log('found data', results);
});
我的数据像 ['2', '13', '13A', '14-1']
,我怎样才能得到 filter
的正确顺序?谢谢大家。
IIUC,您将数字(2
、10
等)作为字符串('2'
、'10'
等)存储在数据库中。
LoopBack 依赖于数据库来执行排序(排序)。
这里有一些尝试:
修改您的模型定义以将 属性 存储为
number
。 LoopBack 很聪明,会在将用户(REST API 客户端)提供的字符串值存储到数据库之前将其强制转换为数字。这将是我的首选解决方案,因为它不需要您的应用程序中的任何复杂代码并保持性能。根据您使用的数据库,可以将其配置为将字符串值视为数字进行排序。这不是特定于 LoopBack 的,我真的帮不了你。
作为最后的手段,您可以对内存中的记录进行排序,当数据库不支持基于位置的查询时,LoopBack 已经这样做了。这个想法是告诉数据库 return 所有 符合
filter
条件的记录,然后应用order
、limit
、skip
和 Node.js 进程中的其他选项。请注意,这会严重影响性能,并且仅适用于合理大小的数据。
至于第三个选项:在实现方面,您需要覆盖模型中的 find
方法 class。
// common/models/my-model.js
module.exports = function(MyModel) {
MyModel.on('modelRemoted', () => {
MyModel._findRaw = MyModel.find;
MyModel.find = findWithCustomSort;
});
}
function findWithCustomSort(filter, options, cb) {
if (!cb) {
if (typeof options === 'function') {
cb = options;
options = undefined;
} else if (!options && typeof filter === 'function') {
cb = filter;
filter = undefined;
}
}
const dbFilter = {
where: filter.where,
include: filter.include,
fields: filter.fields,
};
if (cb) {
this._findRaw(dbFilter, options, (err, found) => {
if (err) return cb(err);
else cb(null, sortResults(filter, found))
});
} else {
return this._findRaw(dbFilter, options)
.then(found => sortResults(filter, found));
}
}
function sortResults(filter, data) {
// implement your sorting rules, don't forget about "limit", "skip", etc.
}
更新
Is there a way to use sql for query in custom method?
是的,您可以使用 MyModel.dataSource.connector.execute
函数执行任何 SQL,请参阅 Executing native SQL。但有一个问题 - 此方法是基于回调的,您不能使用 Promise API 或 async/await.
const idValue = 1;
MyModel.dataSource.connector.execute(
'SELECT * FROM MyModel WHERE id=?',
[idValue]
(err, results) => {
if (err) console.error('query failed', err);
else console.log('found data', results);
});