我想使用带有admin-on-rest的全文过滤器来查询来自我的回送服务器的数据。 我试图从文档(AOR-doc)中实现该示例,但遗憾的是我只设法查询单个字段:
const CatFilter = (props) => (
<Filter {...props}>
<TextInput label="Search" source="CatCode" alwaysOn />
</Filter>
);
如何使用环回后端跨多个字段执行全文搜索,以搜索&#34;包含&#34;如果可能的话。
答案 0 :(得分:3)
有两种方法可以做到这一点,我在下面概述。
1)Loopback全文搜索需要一个执行Regex搜索的自定义远程方法。
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)
}
这里的一个小小的hackyness我想在过滤器中分配一个虚拟源,如上面的userNameOrEmail。虽然它并没有真正压倒任何默认问题。只是帮助我们设置适当的过滤器
2)您也可以通过在自定义Rest Wrapper或您自己的Rest Client中执行上述函数findUsersByNameOrEmail之类的过滤器构造来实现相同的功能。所以在你的rest客户端或包装器中就像下面这样的东西。
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的调用,并根据需要事先修复。
答案 1 :(得分:2)
最后,我想我找到了一个似乎运作良好的解决方案。我希望我没有忽略任何问题,以便解决方案可以帮助别人或让我意识到错误。 首先我在MongoDB中创建了一个Text Index
db.collection.createIndex( { "$**": "text" } )
在Loopback中,我在die model-name.js中创建了一个access operation-hook,它捕获全文查询“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();
});
管理员休息代码中的过滤器保留在示例中:
const CatFilter = (props) => {
return (<Filter {...props}>
<TextInput label="Full Text Search" source="q" alwaysOn />
</Filter>)
}