【问题标题】:Using Sequelize to find all images by related keyword with an array of keyword ID values to include / exclude使用 Sequelize 按相关关键字查找所有图像,其中包含要包含/排除的关键字 ID 值数组
【发布时间】:2019-04-27 02:40:20
【问题描述】:

我有一个 Node.js/Express/Sequelize 项目,我在其中存储了一个包含相关关键字的图像库,并且我希望能够通过这些关键字搜索图像。

我有一个与关键字具有多对多关系的图像表,以及与图像具有多对多关系的关键字表。

Image.belongsToMany(Keywords, {
  as: 'keywords',
  through: {
    model: ImageKeywords,
    unique: false
  },
  foreignKey: 'image_id',
  constraints: false
});

Keywords.belongsToMany(Image, {
  as: 'image',
  through: {
    model: ImageKeywords,
    unique: false
  },
  foreignKey: 'keyword_id',
  constraints: false
});

我有一组关键字 ID 可以使用 AND 进行搜索,还有一组关键字要使用 NOT 从搜索中排除。这些是由用户通过搜索表单输入的,但本质上是以下结构。

let keywordsAnd = [1,2,3]
let keywordsNot = [4,5,6]

对于每张图片,我通过连接表关联了一个或多个关键字,并且可以毫无困难地获取图像并显示所有关键字。

我想要完成的是,当用户输入他们想要搜索的关键字列表并指定要排除的一些关键字时,我想使用带关键字和数组的 AND 搜索来查找所有图像,然后排除在keywordsNot数组中的那些。

对于上面的示例,我想返回与 ID 为 1、2 或 3 的所有关键字相关联的任何图像,并排除与 ID 4、5 或 6 的任何关键字相关联的任何图像。

我试图通过 Keywords.findAll 路径使用以下内容:

   Keywords.findAll({
        include: [{
            model: Image,
            as: 'image',
            include: [{
                model: Keywords,
                as: 'keywords',
                attributes: ['id', 'name']
            }]
        }],
        where: { 
            id: {
                [Op.and]: [
                    keywordsAnd,
                    { [Op.not]: keywordsNot }
                ]
            }
        }
    })

这似乎使用关键字和数组进行 OR 搜索,如果定义了关键字,则会引发错误。

所以使用上面的 [1,2,3] 数组,我得到了所有关键字 ID 为 1、2 或 3 的图像。

我突然想到,也许我应该通过 Image.findAll 进行搜索,包括关键字模型,但我目前对 Sequelize 的机制还不够熟悉,无法知道正确的方法和语法,所以任何指导都会不胜感激。

【问题讨论】:

    标签: javascript node.js sequelize.js


    【解决方案1】:

    首先,您可以使用Image.findAll 而不是Keywords.findAll 作为第一个查询,并在使用include 内使用SQL 查询级别的关键字创建连接。

    include 中,您可以添加一个where 子句,如上所示,以更改Keywords 研究。

    最后你可以使用Op.inOp.notIn,它们都用于处理数组。

    请参阅Sequelize documentation 并特别注意Relations / AssociationsOperators 部分。

    希望对你有帮助!

    Image.findAll({
      include: [ {
        model: Keywords,
        as: 'Keywords',
        attributes: ['id', 'name'],
        where: {
          id: {
            [Op.and]: [
              { [Op.in]: keywordsAnd },
              { [Op.notIn]: keywordsNot }
            ]
          }
        }
      } ]
    });
    
    

    【讨论】:

    • 其中的 [Op.in] 部分正在工作,但 [Op.notIn] 部分不排除带有关键字的图像在 keywordsNot 数组中。我不确定我在这里缺少什么。
    猜你喜欢
    • 1970-01-01
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多