Sequelize

时间:2017-07-31 12:20:07

标签: node.js postgresql express sequelize.js

我目前正在使用ExpressJS,PostgreSQL和Sequelize作为ORM的项目。我开发了一个搜索功能,它使查询按名称搜索项目:

models.foo.findAll({
  where: {
    $or: [
      {name: {$ilike: keywords}},
      {searchMatches: {$contains: [keywords]}}
    ]
  },
  order: [['name', 'ASC']]
})

这样可以正常工作,但如果名称包含特殊字符(如á,é,í,ó或ú),则此查询将无法找到它。

有没有办法让查询搜索名称具有有意义的特殊字符?就像我搜索“马铃薯”这个名字一样,结果“土豆”,“Dapotátos”和“我们是pótatóes”会出来,但不是“我们吃pátatos”(因为á!= o)

4 个答案:

答案 0 :(得分:2)

我终于找到了一个有效的解决方案。首先我创建了unaccent扩展:

create extension unaccent;

然后我只使用了一个原始查询(我无法弄清楚如何使用Sequelize的方式构建查询),如下所示:

models.sequelize.query(
    `SELECT
      *
    FROM
      "Foos"
    WHERE
      unaccent("name") ilike unaccent('${keywords}')          
      OR "searchMatches" @> ARRAY[unaccent('${keywords}')]::VARCHAR(255)[]
    ORDER BY
      "name" ASC`, {model: models.Foo})

它有效!

答案 1 :(得分:1)

现在可以在没有完全RAW查询的情况下完成,但在内置函数中使用Sequelize:

models.foo.findAll({
  where: Sequelize.where(
    Sequelize.fn('unaccent', Sequelize.col('name')), {
        [Op.iLike]:`%${keywords}%`
  }),
  order: [['name', 'ASC']]
})

然后排序,关联等所有工作仍然正常:)。

答案 2 :(得分:0)

字典可能就是你要找的东西。基本上可以用来映射同义词并从索引中排除常见元素(例如" a"""来自英文文本)等等。

https://www.postgresql.org/docs/current/static/textsearch-dictionaries.html

答案 3 :(得分:0)

在我的情况下,我使用Sequelize.literal和COLLATE解决了这个问题:

where: Sequelize.literal(`name COLLATE Latin1_general_CI_AI like '%${keywords}%' COLLATE Latin1_general_CI_AI`)

那样,消除两侧的口音。