如何在环回服务器上使用 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>)
}