Sequelize-nodejs-5-Querying


Querying查詢

Attributes

To select only some attributes, you can use the attributes option. Most often, you pass an array:

為了收集一些屬性,可以使用attributes選項:

Model.findAll({
  attributes: ['foo', 'bar']
});

//等價於
SELECT foo, bar ...

 

Attributes can be renamed using a nested array:

屬性能夠使用嵌套數組進行重命名:

Model.findAll({
  attributes: ['foo', ['bar', 'baz']]
});

//等價於
SELECT foo, bar AS baz ...

 

You can use sequelize.fn to do aggregations:

可以使用sequelize.fn進行聚合:

Model.findAll({
  attributes: [[sequelize.fn('COUNT', sequelize.col('hats')), 'no_hats']]
});

SELECT COUNT(hats) AS no_hats ...

When using aggregation function, you must give it an alias to be able to access it from the model. In the example above you can get the number of hats with instance.get('no_hats').

當使用聚合函數時,你一定要給它一個別名來使其能夠從模型中被訪問(上面就是為聚合函數COUNT(hats)起了no_hats別名)。在上面的例子中,你可以通過instance.get('no_hats')得到hats的數量

Sometimes it may be tiresome to list all the attributes of the model if you only want to add an aggregation:

有時當你想要添加聚合時,你可能會厭倦列舉模型的所有的屬性:

// This is a tiresome way of getting the number of hats...
Model.findAll({
  attributes: ['id', 'foo', 'bar', 'baz', 'quz', [sequelize.fn('COUNT', sequelize.col('hats')), 'no_hats']]
});

//更短的方法,可不用列舉屬性
// This is shorter, and less error prone because it still works if you add / remove attributes
Model.findAll({
  attributes: { include: [[sequelize.fn('COUNT', sequelize.col('hats')), 'no_hats']] }
});

SELECT id, foo, bar, baz, quz, COUNT(hats) AS no_hats ...

Similarly, it's also possible to remove a selected few attributes:

相似地,可以移除選出的一些屬性

Model.findAll({
  attributes: { exclude: ['baz'] }
});

SELECT id, foo, bar, quz ...

 

 

 

Where

Whether you are querying with findAll/find or doing bulk updates/destroys you can pass a where object to filter the query.

無論你是通過findAll/find進行查詢或是進行大量地updates/destroys操作,你都可以使用where對象來過濾查詢

where generally takes an object from attribute:value pairs, where value can be primitives for equality matches or keyed objects for other operators.

通常where從attribute:value對中取出對象,value可能是平等匹配的原語或其他操作符的鍵值對象

It's also possible to generate complex AND/OR conditions by nesting sets of or and and Operators.

通過嵌套orand操作符集生成復雜的AND/OR條件是可能的

Basics

const Op = Sequelize.Op;

Post.findAll({
  where: {
    authorId: 2
  }
});
//等價於
// SELECT * FROM post WHERE authorId = 2

Post.findAll({
  where: {
    authorId: 12,
    status: 'active'
  }
});
// SELECT * FROM post WHERE authorId = 12 AND status = 'active';

Post.findAll({
  where: {
    [Op.or]: [{authorId: 12}, {authorId: 13}]
  }
});
// SELECT * FROM post WHERE authorId = 12 OR authorId = 13;

Post.findAll({
  where: {
    authorId: {
      [Op.or]: [12, 13]
    }
  }
});
// SELECT * FROM post WHERE authorId = 12 OR authorId = 13;

Post.destroy({
  where: {
    status: 'inactive'
  }
});
// DELETE FROM post WHERE status = 'inactive';

Post.update({
  updatedAt: null,
}, {
  where: {
    deletedAt: {
      [Op.ne]: null
    }
  }
});
// UPDATE post SET updatedAt = null WHERE deletedAt NOT NULL;

Post.findAll({
  where: sequelize.where(sequelize.fn('char_length', sequelize.col('status')), 6)
});
// SELECT * FROM post WHERE char_length(status) = 6;

 

Operators

Sequelize exposes symbol operators that can be used for to create more complex comparisons -

Sequelize暴露symbol操作符,用於創建更多復雜的比較:

const Op = Sequelize.Op

[Op.and]: {a: 5}           // AND (a = 5)
[Op.or]: [{a: 5}, {a: 6}]  // (a = 5 OR a = 6)
[Op.gt]: 6,                // > 6
[Op.gte]: 6,               // >= 6
[Op.lt]: 10,               // < 10
[Op.lte]: 10,              // <= 10
[Op.ne]: 20,               // != 20
[Op.eq]: 3,                // = 3
[Op.not]: true,            // IS NOT TRUE
[Op.between]: [6, 10],     // BETWEEN 6 AND 10
[Op.notBetween]: [11, 15], // NOT BETWEEN 11 AND 15
[Op.in]: [1, 2],           // IN [1, 2]
[Op.notIn]: [1, 2],        // NOT IN [1, 2]
[Op.like]: '%hat',         // LIKE '%hat'
[Op.notLike]: '%hat'       // NOT LIKE '%hat'
[Op.iLike]: '%hat'         // ILIKE '%hat' (case insensitive) (PG only)
[Op.notILike]: '%hat'      // NOT ILIKE '%hat'  (PG only)
[Op.regexp]: '^[h|a|t]'    // REGEXP/~ '^[h|a|t]' (MySQL/PG only)
[Op.notRegexp]: '^[h|a|t]' // NOT REGEXP/!~ '^[h|a|t]' (MySQL/PG only)
[Op.iRegexp]: '^[h|a|t]'    // ~* '^[h|a|t]' (PG only)
[Op.notIRegexp]: '^[h|a|t]' // !~* '^[h|a|t]' (PG only)
[Op.like]: { [Op.any]: ['cat', 'hat']}
                       // LIKE ANY ARRAY['cat', 'hat'] - also works for iLike and notLike
[Op.overlap]: [1, 2]       // && [1, 2] (PG array overlap operator)
[Op.contains]: [1, 2]      // @> [1, 2] (PG array contains operator)
[Op.contained]: [1, 2]     // <@ [1, 2] (PG array contained by operator)
[Op.any]: [2,3]            // ANY ARRAY[2, 3]::INTEGER (PG only)

[Op.col]: 'user.organization_id' // = "user"."organization_id", with dialect specific column identifiers, PG in this example

 

Range Operators范圍操作符

Range types can be queried with all supported operators.

Range類型可以在所有支持的操作符中使用

Keep in mind, the provided range value can define the bound inclusion/exclusion as well.

注意,提供的范圍值也可以定義邊界的閉包,即[為閉口,(為開口。

// All the above equality and inequality operators plus the following:

[Op.contains]: 2           // @> '2'::integer (PG range contains element operator)
[Op.contains]: [1, 2]      // @> [1, 2) (PG range contains range operator)
[Op.contained]: [1, 2]     // <@ [1, 2) (PG range is contained by operator)
[Op.overlap]: [1, 2]       // && [1, 2) (PG range overlap (have points in common) operator)
[Op.adjacent]: [1, 2]      // -|- [1, 2) (PG range is adjacent to operator)
[Op.strictLeft]: [1, 2]    // << [1, 2) (PG range strictly left of operator)
[Op.strictRight]: [1, 2]   // >> [1, 2) (PG range strictly right of operator)
[Op.noExtendRight]: [1, 2] // &< [1, 2) (PG range does not extend to the right of operator)
[Op.noExtendLeft]: [1, 2]  // &> [1, 2) (PG range does not extend to the left of operator)

 

Combinations連接起來使用

const Op = Sequelize.Op;

{
  rank: {
    [Op.or]: {
      [Op.lt]: 1000,
      [Op.eq]: null
    }
  }
}
// rank < 1000 OR rank IS NULL

{
  createdAt: {
    [Op.lt]: new Date(),
    [Op.gt]: new Date(new Date() - 24 * 60 * 60 * 1000)
  }
}
// createdAt < [timestamp] AND createdAt > [timestamp]

{
  [Op.or]: [
    {
      title: {
        [Op.like]: 'Boat%'
      }
    },
    {
      description: {
        [Op.like]: '%boat%'
      }
    }
  ]
}
// title LIKE 'Boat%' OR description LIKE '%boat%'

 

Operators Aliases操作符別名

Sequelize allows setting specific strings as aliases for operators -

Sequelize允許設置指定的字符串作為操作符的別名

const Op = Sequelize.Op;
const operatorsAliases = {
  $gt: Op.gt
}
const connection = new Sequelize(db, user, pass, { operatorsAliases })

[Op.gt]: 6 // > 6
$gt: 6 // same as using Op.gt (> 6)

 

Operators security操作符安全性

Using Sequelize without any aliases improves security. Some frameworks automatically parse user input into js objects and if you fail to sanitize your input it might be possible to inject an Object with string operators to Sequelize.

使用沒有任何別名的Sequelize提高了安全性。有些框架自動解析用戶輸入到js對象如果你未能清潔你的輸入有可能注入Sequelize對象和字符串運算符

Not having any string aliases will make it extremely unlikely that operators could be injected but you should always properly validate and sanitize user input.

向后兼容性原因Sequelize默認設置下面的別名 - $eq, $ne, $gte, $gt, $lte, $lt, $not, $in, $notIn, $is, $like, $notLike, $iLike, $notILike, $regexp, $notRegexp, $iRegexp, $notIRegexp, $between, $notBetween, $overlap, $contains, $contained, $adjacent, $strictLeft, $strictRight, $noExtendRight, $noExtendLeft, $and, $or, $any, $all, $values, $col

目前以下遺留別名也被設置,但計划在不久的將來被完全移除 - ne, not, in, notIn, gte, gt, lte, lt, like, ilike, $ilike, nlike, $notlike, notilike, .., between, !.., notbetween, nbetween, overlap, &&, @>, <@

For better security it is highly advised to use Sequelize.Op and not depend on any string alias at all. You can limit alias your application will need by setting operatorsAliases option, remember to sanitize user input especially when you are directly passing them to Sequelize methods.

為了更好的安全,強烈建議使用Sequelize.Op和不依賴於任何字符串的別名。你可以通過設置別名operatorsAliases選項來限制你的應用程序需要的別名,記得要檢查用戶輸入特別是當你直接傳遞他們給Sequelize的方法。

const Op = Sequelize.Op; //use sequelize without any operators aliases,不使用別名 const connection = new Sequelize(db, user, pass, { operatorsAliases: false }); //use sequelize with only alias for $and => Op.and,只使用Op.and一個別名 const connection2 = new Sequelize(db, user, pass, { operatorsAliases: { $and: Op.and } });

Sequelize will warn you if you're using the default aliases and not limiting them if you want to keep using all default aliases (excluding legacy ones) without the warning you can pass the following operatorsAliases option -

如果你使用默認的別名並沒有進行限制,Sequelize會警告你,所以我得到了上面的警告。

如果你想繼續使用所有缺省別名(不包括遺留的)沒有警告,您可以通過設置以下operatorsAliases選項:

const Op = Sequelize.Op; const operatorsAliases = { $eq: Op.eq, $ne: Op.ne, $gte: Op.gte, $gt: Op.gt, $lte: Op.lte, $lt: Op.lt, $not: Op.not, $in: Op.in, $notIn: Op.notIn, $is: Op.is, $like: Op.like, $notLike: Op.notLike, $iLike: Op.iLike, $notILike: Op.notILike, $regexp: Op.regexp, $notRegexp: Op.notRegexp, $iRegexp: Op.iRegexp, $notIRegexp: Op.notIRegexp, $between: Op.between, $notBetween: Op.notBetween, $overlap: Op.overlap, $contains: Op.contains, $contained: Op.contained, $adjacent: Op.adjacent, $strictLeft: Op.strictLeft, $strictRight: Op.strictRight, $noExtendRight: Op.noExtendRight, $noExtendLeft: Op.noExtendLeft, $and: Op.and, $or: Op.or, $any: Op.any, $all: Op.all, $values: Op.values, $col: Op.col }; const connection = new Sequelize(db, user, pass, { operatorsAliases });

 

JSON

The JSON data type is supported by the PostgreSQL, SQLite and MySQL dialects only. 

JSON數據類型只被PostgreSQL, SQLite and MySQL支持

PostgreSQL

The JSON data type in PostgreSQL stores the value as plain text, as opposed to binary representation. If you simply want to store and retrieve a JSON representation, using JSON will take less disk space and less time to build from its input representation. However, if you want to do any operations on the JSON value, you should prefer the JSONB data type described below.

在PostgreSQL中的JSON數據類型以純文本的形式存儲值,而不是二進制表示法。如果你只想存儲和檢索JSON表示法,那么使用JSON將會占用更少內存和時間來從它的輸入表示法中構建數據。可是,如果你想要對json值進行一些操作,你會更偏向於下面提到的JSONB數據類型

MSSQL

MSSQL does not have a JSON data type, however it does provide support for JSON stored as strings through certain functions since SQL Server 2016. Using these functions, you will be able to query the JSON stored in the string, but any returned values will need to be parsed seperately. 

MSSQL沒有JSON數據類型,可是從SQL Server 2016起,他就通過一些函數提供將JSON存儲為字符串的支持。使用這些函數,你將能夠查詢存儲在字符串中的JSON,但是任何返回結果都需要分開解析

// ISJSON - to test if a string contains valid JSON
User.findAll({
  where: sequelize.where(sequelize.fn('ISJSON', sequelize.col('userDetails')), 1)
})

// JSON_VALUE - extract a scalar value from a JSON string
User.findAll({
  attributes: [[ sequelize.fn('JSON_VALUE', sequelize.col('userDetails'), '$.address.Line1'), 'address line 1']]
})

// JSON_VALUE - query a scalar value from a JSON string
User.findAll({
  where: sequelize.where(sequelize.fn('JSON_VALUE', sequelize.col('userDetails'), '$.address.Line1'), '14, Foo Street')
})

// JSON_QUERY - extract an object or array
User.findAll({
  attributes: [[ sequelize.fn('JSON_QUERY', sequelize.col('userDetails'), '$.address'), 'full address']]
})

 

JSONB

JSONB can be queried in three different ways.

可以以下面三種不同方式進行查詢:

Nested object

{
  meta: {
    video: {
      url: {
        [Op.ne]: null
      }
    }
  }
}

Nested key

{
  "meta.audio.length": {
    [Op.gt]: 20
  }
}

Containment

{
  "meta": {
    [Op.contains]: {
      site: {
        url: 'http://google.com'
      }
    }
  }
}

 

Relations / Associations關聯性

// Find all projects with a least one task where task.state === project.state
Project.findAll({
    include: [{
        model: Task,
        where: { state: Sequelize.col('project.state') }
    }]
})

 

 

 

Pagination / Limiting限制

// Fetch 10 instances/rows
Project.findAll({ limit: 10 })

// Skip 8 instances/rows
Project.findAll({ offset: 8 })

// Skip 5 instances and fetch the 5 after that
Project.findAll({ offset: 5, limit: 5 })

 

 

Ordering排序

order takes an array of items to order the query by or a sequelize method. Generally you will want to use a tuple/array of either attribute, direction or just direction to ensure proper escaping.

order通過sequelize方獲得數組項去排序查詢。通常需要使用每個元組/數組的屬性,方向或僅僅是方向,以確保適當的排除。

Subtask.findAll({
  order: [
    // Will escape title and validate DESC against a list of valid direction parameters
    ['title', 'DESC'],

    // Will order by max(age)
    sequelize.fn('max', sequelize.col('age')),

    // Will order by max(age) DESC
    [sequelize.fn('max', sequelize.col('age')), 'DESC'],

    // Will order by  otherfunction(`col1`, 12, 'lalala') DESC
    [sequelize.fn('otherfunction', sequelize.col('col1'), 12, 'lalala'), 'DESC'],

    // Will order an associated model's created_at using the model name as the association's name.
    [Task, 'createdAt', 'DESC'],

    // Will order through an associated model's created_at using the model names as the associations' names.
    [Task, Project, 'createdAt', 'DESC'],

    // Will order by an associated model's created_at using the name of the association.
    ['Task', 'createdAt', 'DESC'],

    // Will order by a nested associated model's created_at using the names of the associations.
    ['Task', 'Project', 'createdAt', 'DESC'],

    // Will order by an associated model's created_at using an association object. (preferred method)
    [Subtask.associations.Task, 'createdAt', 'DESC'],

    // Will order by a nested associated model's created_at using association objects. (preferred method)
    [Subtask.associations.Task, Task.associations.Project, 'createdAt', 'DESC'],

    // Will order by an associated model's created_at using a simple association object.
    [{model: Task, as: 'Task'}, 'createdAt', 'DESC'],

    // Will order by a nested associated model's created_at simple association objects.
    [{model: Task, as: 'Task'}, {model: Project, as: 'Project'}, 'createdAt', 'DESC']
  ]

  // Will order by max age descending
  order: sequelize.literal('max(age) DESC')

  // Will order by max age ascending assuming ascending is the default order when direction is omitted
  order: sequelize.fn('max', sequelize.col('age'))

  // Will order by age ascending assuming ascending is the default order when direction is omitted
  order: sequelize.col('age')

  // Will order randomly based on the dialect (instead of fn('RAND') or fn('RANDOM'))
  order: sequelize.random()
})

 

 

 

 

Table Hint表提示

tableHint can be used to optionally pass a table hint when using mssql. The hint must be a value from Sequelize.TableHints and should only be used when absolutely necessary. Only a single table hint is currently supported per query. 

tableHint可以在使用mssql時選擇性地傳遞一些表提示。提示必須是來自Sequelize.TableHints的值並只有在必須的時候才使用。現在在每個查詢中只有單表提示被支持

Table hints override the default behavior of mssql query optimizer by specifing certain options. They only affect the table or view referenced in that clause.

表提示通過指定某些選項來覆蓋mssql查詢優化器的默認行為。他們僅僅影響表或子句中的視圖引用

const TableHints = Sequelize.TableHints;

Project.findAll({
  // adding the table hint NOLOCK
  tableHint: TableHints.NOLOCK
  // this will generate the SQL 'WITH (NOLOCK)'
})

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM