如何在环回服务器上使用 admin-on-rest 进行全文过滤
How to full-text filter with admin-on-rest on loopback server
我想在 admin-on-rest 中使用全文过滤器从我的环回服务器查询数据。
我试图实现文档中的示例 (AOR-doc),但不幸的是我只能查询单个字段:
const CatFilter = (props) => (
<Filter {...props}>
<TextInput label="Search" source="CatCode" alwaysOn />
</Filter>
);
如何使用环回后端执行跨多个字段的全文搜索,如果可能,将搜索 "contains" 字符串。
有两种方法可以做到这一点,我在下面概述了这两种方法。
1) 环回全文搜索需要一个执行正则表达式搜索的自定义远程方法。
https://loopback.io/doc/en/lb3/Where-filter.html
跳转到正则表达式部分。
这是我能找到的在 LB 中进行文本搜索的最佳方式。
这是我的过滤器
const AdminFilter = (props) => {
return (<Filter {...props}>
<TextInput label="Name Or Email" source="userNameOrEmailId" alwaysOn />
</Filter>)
}
这会在 API 端生成以下形式的过滤器。
const findUsersByNameOrEmail = (filter) => {
const regex = '^' + filter.where.userNameOrEmailId
filter.where.or = [{name: {'regexp': regex}}, {email: {'regexp': regex}}]
delete filter.where.userNameOrEmailId
return findAllUsersByFilter(filter)
}
const findAllUsersByFilter = (filter) => {
return AppUser.find(filter)
}
我想这里有个小问题是在过滤器中分配一个虚拟源,如上面的 userNameOrEmail。尽管它并没有真正覆盖任何默认问题。只是帮助我们设置适当的过滤器。
2) 您也可以通过在自定义 Rest Wrapper 或您自己的 Rest Client 中执行类似 findUsersByNameOrEmail 上面的函数 findUsersByNameOrEmail 完成的过滤器构造来实现相同的目的。因此,在您的其余客户端或包装器中,如下所示。
if (type === 'GET_LIST' && resource === 'appUser') {
const regex = '^' + params.userNameOrEmailId
const url = `URLroot/filter={where: [or: {name: {'regexp': regex}}, {email: {'regexp': regex}}]
options.method = 'GET';
return handleRequestAndResponse(url, options)
}
我们的想法是拦截对您的 API 的调用,并根据需要预先修复。
最后,我想我找到了一个似乎行之有效的解决方案。我希望我没有忽略任何问题,以便解决方案可以帮助其他人或让我意识到错误。
首先我在 MongoDB
中创建了一个 Text Index
db.collection.createIndex( { "$**": "text" } )
在 Loopback 中,我创建了一个 access operation-hook in die model-name.js 来捕获全文查询 "q" 并进行直接数据库查询:
Clinic.observe('access', function logQuery(ctx, next) {
console.log('Accessing %s matching %s', JSON.stringify(ctx.Model.modelName), JSON.stringify(ctx.query.where));
if (ctx && ctx.query && ctx.query.where && ctx.query.where.q) {
ctx.query.where =
{$text:
{
search: ctx.query.where.q,
language: "de",
caseSensitive: false,
diacriticSensitive: false
}
}
}
next();
});
admin-on-rest 代码中的 Filter 与示例中的一样:
const CatFilter = (props) => {
return (<Filter {...props}>
<TextInput label="Full Text Search" source="q" alwaysOn />
</Filter>)
}
我想在 admin-on-rest 中使用全文过滤器从我的环回服务器查询数据。 我试图实现文档中的示例 (AOR-doc),但不幸的是我只能查询单个字段:
const CatFilter = (props) => (
<Filter {...props}>
<TextInput label="Search" source="CatCode" alwaysOn />
</Filter>
);
如何使用环回后端执行跨多个字段的全文搜索,如果可能,将搜索 "contains" 字符串。
有两种方法可以做到这一点,我在下面概述了这两种方法。
1) 环回全文搜索需要一个执行正则表达式搜索的自定义远程方法。
https://loopback.io/doc/en/lb3/Where-filter.html
跳转到正则表达式部分。
这是我能找到的在 LB 中进行文本搜索的最佳方式。
这是我的过滤器
const AdminFilter = (props) => {
return (<Filter {...props}>
<TextInput label="Name Or Email" source="userNameOrEmailId" alwaysOn />
</Filter>)
}
这会在 API 端生成以下形式的过滤器。
const findUsersByNameOrEmail = (filter) => {
const regex = '^' + filter.where.userNameOrEmailId
filter.where.or = [{name: {'regexp': regex}}, {email: {'regexp': regex}}]
delete filter.where.userNameOrEmailId
return findAllUsersByFilter(filter)
}
const findAllUsersByFilter = (filter) => {
return AppUser.find(filter)
}
我想这里有个小问题是在过滤器中分配一个虚拟源,如上面的 userNameOrEmail。尽管它并没有真正覆盖任何默认问题。只是帮助我们设置适当的过滤器。
2) 您也可以通过在自定义 Rest Wrapper 或您自己的 Rest Client 中执行类似 findUsersByNameOrEmail 上面的函数 findUsersByNameOrEmail 完成的过滤器构造来实现相同的目的。因此,在您的其余客户端或包装器中,如下所示。
if (type === 'GET_LIST' && resource === 'appUser') {
const regex = '^' + params.userNameOrEmailId
const url = `URLroot/filter={where: [or: {name: {'regexp': regex}}, {email: {'regexp': regex}}]
options.method = 'GET';
return handleRequestAndResponse(url, options)
}
我们的想法是拦截对您的 API 的调用,并根据需要预先修复。
最后,我想我找到了一个似乎行之有效的解决方案。我希望我没有忽略任何问题,以便解决方案可以帮助其他人或让我意识到错误。 首先我在 MongoDB
中创建了一个 Text Indexdb.collection.createIndex( { "$**": "text" } )
在 Loopback 中,我创建了一个 access operation-hook in die model-name.js 来捕获全文查询 "q" 并进行直接数据库查询:
Clinic.observe('access', function logQuery(ctx, next) {
console.log('Accessing %s matching %s', JSON.stringify(ctx.Model.modelName), JSON.stringify(ctx.query.where));
if (ctx && ctx.query && ctx.query.where && ctx.query.where.q) {
ctx.query.where =
{$text:
{
search: ctx.query.where.q,
language: "de",
caseSensitive: false,
diacriticSensitive: false
}
}
}
next();
});
admin-on-rest 代码中的 Filter 与示例中的一样:
const CatFilter = (props) => {
return (<Filter {...props}>
<TextInput label="Full Text Search" source="q" alwaysOn />
</Filter>)
}