MongoDB规则表达式研究过程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/it_monkey_ali/article/details/83345205
  1. 普通查询规则
    1. 准备如下数据

db.inventory.insertMany([

   { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },

   { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },

   { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },

   { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },

   { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }

]);

 

db.inventory.insertMany([

   { item: "computer", qty: 75, size: { h: 84, w: 61, uom: "cm" }, status: "B" },

   { item: "bicycle", qty: 60, size: { h: 43.5, w: 111, uom: "in" }, status: "C" },

   { item: "flower", qty: 90, size: { h: 28.5, w: 41, uom: "cm" }, status: "C" },

   { item: "friend", qty: 55, size: { h: 33.95, w: 180, uom: "in" }, status: "B" },

   { item: "bigtree", qty: 145, size: { h: 100, w: 644.25, uom: "cm" }, status: "E" }

]);

 

    1. 数据插入

> db.inventory.insertMany([

...    { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },

...    { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },

...    { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },

...    { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },

...    { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }

... ]);

{

  "acknowledged" : true,

  "insertedIds" : [

         ObjectId("5bcd404ccfe6723a348dce06"),

         ObjectId("5bcd404ccfe6723a348dce07"),

         ObjectId("5bcd404ccfe6723a348dce08"),

         ObjectId("5bcd404ccfe6723a348dce09"),

         ObjectId("5bcd404ccfe6723a348dce0a")

  ]

}

 

    1. 显示表

> show tables;

inventory

mylog

 

    1. 全量查询

> db.inventory.find();

{ "_id" : ObjectId("5bcd404ccfe6723a348dce06"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce07"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce08"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce09"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "status" : "D" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce0a"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "A" }

 

> db.inventory.find({});

{ "_id" : ObjectId("5bcd404ccfe6723a348dce06"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce07"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce08"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce09"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "status" : "D" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce0a"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "A" }

 

    1. 指定相等条件查询

To specify equality conditions, use <field>:<value> expressions in the query filter document:

{ <field1>: <value1>, ... }

 

> db.inventory.find( { status: "D" } )

{ "_id" : ObjectId("5bcd404ccfe6723a348dce08"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce09"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "status" : "D" }

 

    1. 指定条件使用查询操作

A query filter document can use the query operators to specify conditions in the following form:

{ <field1>: { <operator1>: <value1> }, ... }

 

> db.inventory.find( { status: { $in: [ "A", "D" ] } } )

{ "_id" : ObjectId("5bcd404ccfe6723a348dce06"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce07"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce08"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce09"), "item" : "planner", "qty" : 75, "size" : { "h" : 22.85, "w" : 30, "uom" : "cm" }, "status" : "D" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce0a"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "A" }

 

> db.inventory.find( { status: { $in: [ "A", "C" ] } } )

{ "_id" : ObjectId("5bcd404ccfe6723a348dce06"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce07"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce0a"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "A" }

 

  1. NOTE
  2. Although you can express this query using the $or operator, use the $in operator rather than the $or operator when performing equality checks on the same field.

 

    1. 指定And条件

A compound query can specify conditions for more than one field in the collection’s documents. Implicitly, a logical AND conjunction connects the clauses of a compound query so that the query selects the documents in the collection that match all the conditions.

 

The following example retrieves all documents in the inventory collection where the status equals "A" and qty is less than ($lt) 30:

 

> db.inventory.find( { status: "A", qty: { $lt: 30 } } )

{ "_id" : ObjectId("5bcd404ccfe6723a348dce06"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }

 

> db.inventory.find( { status: "B", qty: { $lt: 80 } } )

{ "_id" : ObjectId("5bcd47afcfe6723a348dce0b"), "item" : "computer", "qty" : 75, "size" : { "h" : 84, "w" : 61, "uom" : "cm" }, "status" : "B" }

{ "_id" : ObjectId("5bcd47afcfe6723a348dce0e"), "item" : "friend", "qty" : 55, "size" : { "h" : 33.95, "w" : 180, "uom" : "in" }, "status" : "B" }

 

> db.inventory.find( { status: "B", qty: { $lt: 50 } } )

 

> db.inventory.find( { status: "B", qty: { $lt: 60 } } )

{ "_id" : ObjectId("5bcd47afcfe6723a348dce0e"), "item" : "friend", "qty" : 55, "size" : { "h" : 33.95, "w" : 180, "uom" : "in" }, "status" : "B" }

> db.inventory.find( { status: "B", qty: { $gt: 60 } } )

{ "_id" : ObjectId("5bcd47afcfe6723a348dce0b"), "item" : "computer", "qty" : 75, "size" : { "h" : 84, "w" : 61, "uom" : "cm" }, "status" : "B" }

 

    1. 指定 Or条件

Using the $or operator, you can specify a compound query that joins each clause with a logical OR conjunction so that the query selects the documents in the collection that match at least one condition.

 

The following example retrieves all documents in the collection where the status equals "A" or qty is less than ($lt) 30:

 

> db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )

{ "_id" : ObjectId("5bcd404ccfe6723a348dce06"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce07"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce0a"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "A" }

 

    1. 指定And、Or条件

In the following example, the compound query document selects all documents in the collection where the status equals "A" and either qty is less than ($lt) 30 or item starts with the character p:

 

In the following example, the compound query document selects all documents in the collection where the status equals "A" and either qty is less than ($lt) 30 or item starts with the character p:

 

> db.inventory.find( {      status: "A", $or: [ { qty: { $lt: 30 } }, { item: /^p/ } ] } )

{ "_id" : ObjectId("5bcd404ccfe6723a348dce06"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce0a"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "A" }

 

NOTE

MongoDB supports regular expressions $regex queries to perform string pattern matches.

 

  1. 正则表达式
    1. Definition
      1. $regex

Provides regular expression capabilities for pattern matching strings in queries. MongoDB uses Perl compatible regular expressions (i.e. “PCRE” ) version 8.41 with UTF-8 support.

 

To use $regex, use one of the following syntaxes:

{ <field>: { $regex: /pattern/, $options: '<options>' } }

{ <field>: { $regex: 'pattern', $options: '<options>' } }

{ <field>: { $regex: /pattern/<options> } }

 

In MongoDB, you can also use regular expression objects (i.e. /pattern/) to specify regular expressions:

{ <field>: /pattern/<options> }

 

      1. $options

The following <options> are available for use with regular expression.

i m x s

 

    1. Behavior

$regex vs. /pattern/ Syntax

      1. $in Expressions

To include a regular expression in an $in query expression, you can only use JavaScript regular expression objects (i.e. /pattern/ ). For example:

{ name: { $in: [ /^acme/i, /^ack/ ] } }

  1. You cannot use $regex operator expressions inside an $in.

 

      1. Implicit AND Conditions for the Field

To include a regular expression in a comma-separated list of query conditions for the field, use the $regex operator. For example:

{ name: { $regex: /acme.*corp/i, $nin: [ 'acmeblahcorp' ] } }

{ name: { $regex: /acme.*corp/, $options: 'i', $nin: [ 'acmeblahcorp' ] } }

{ name: { $regex: 'acme.*corp', $options: 'i', $nin: [ 'acmeblahcorp' ] } }

 

      1. x and s Options

To use either the x option or s options, you must use the $regex operator expression with the $options operator. For example, to specify the i and the s options, you must use $options for both:

{ name: { $regex: /acme.*corp/, $options: "si" } }

{ name: { $regex: 'acme.*corp', $options: "si" } }

 

      1. PCRE vs JavaScript

To use PCRE supported features in the regex pattern that are unsupported in JavaScript, you must use the $regex operator expression with the pattern as a string. For example, to use (?i) in the pattern to turn case-insensitivity on for the remaining pattern and (?-i) to turn case-sensitivity on for the remaining pattern, you must use the $regex operator with the pattern as a string:

{ name: { $regex: '(?i)a(?-i)cme' } }

 

      1. Index Use

For case sensitive regular expression queries, if an index exists for the field, then MongoDB matches the regular expression against the values in the index, which can be faster than a collection scan. Further optimization can occur if the regular expression is a “prefix expression”, which means that all potential matches start with the same string. This allows MongoDB to construct a “range” from that prefix and only match against those values from the index that fall within that range.

 

A regular expression is a “prefix expression” if it starts with a caret (^) or a left anchor (\A), followed by a string of simple symbols. For example, the regex /^abc.*/ will be optimized by matching only against the values from the index that start with abc.

 

Additionally, while /^a/, /^a.*/, and /^a.*$/ match equivalent strings, they have different performance characteristics. All of these expressions use an index if an appropriate index exists; however, /^a.*/, and /^a.*$/ are slower. /^a/ can stop scanning after matching the prefix.

 

Case insensitive regular expression queries generally cannot use indexes effectively. The $regex implementation is not collation-aware and is unable to utilize case-insensitive indexes.

 

    1. 正则表达式模式修正符(i、g、m、s、x、e)

l 修正符:  i 不区分大小写的匹配;

l 修正符:g表示全局匹配

l 修正符:  m 将字符串视为多行,不管是那行都能匹配;

l 修正符:s 将字符串视为单行,换行符作为普通字符;

l 修正符:x 将模式中的空白忽略;

l 修正符:A 强制从目标字符串开头匹配;

l 修正符:D 如果使用$限制结尾字符,则不允许结尾有换行;

l 修正符:U 只匹配最近的一个字符串;不重复匹配;

l 修正符:e 配合函数preg_replace()使用, 可以把匹配来的字符串当作正则表达式执行; 

 

 

    1. Examples

The following examples use a collection products with the following documents:

      1. 数据准备

db.regex.insertMany([

  { "_id" : 100, "sku" : "abc123", "description" : "Single line description." },

  { "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" },

  { "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before     line" },

  { "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" },

  { "_id" : 104, "sku" : "lmn123", "description" : "Farley\nI Love you!!!" },

  { "_id" : 105, "sku" : "lmn456", "description" : "Liuling keshimiershan" },

  { "_id" : 106, "sku" : "lmn789", "description" : "LiuFeng\ngugu dddxxxxxxxx" },

  { "_id" : 107, "sku" : "opq123", "description" : "XiongHui\nyour are a dog" },

  { "_id" : 108, "sku" : "opq456", "description" : "Maomaoyu xia si ni mei shangliang" },

  { "_id" : 109, "sku" : "opq789", "description" : "Gaofeng\ndu du a du,ni you are" },

  { "_id" : 110, "sku" : "qaz456", "description" : "Kebi\n da xiong mao siye" },

  { "_id" : 111, "sku" : "qaz789", "description" : "Uou ke bi\nxxxxxxxx t ttttttt" }

]);

 

> db.regex.insertMany([

... { "_id" : 100, "sku" : "abc123", "description" : "Single line description." },

... { "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" },

... { "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before     line" },

... { "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" },

... { "_id" : 104, "sku" : "lmn123", "description" : "Farley\nI Love you!!!" },

... { "_id" : 105, "sku" : "lmn456", "description" : "Liuling keshimiershan" },

... { "_id" : 106, "sku" : "lmn789", "description" : "LiuFeng\ngugu dddxxxxxxxx" },

... { "_id" : 107, "sku" : "opq123", "description" : "XiongHui\nyour are a dog" },

... { "_id" : 108, "sku" : "opq456", "description" : "Maomaoyu xia si ni mei shangliang" },

... { "_id" : 109, "sku" : "opq789", "description" : "Gaofeng\ndu du a du,ni you are" },

... { "_id" : 110, "sku" : "qaz456", "description" : "Kebi\n da xiong mao siye" },

... { "_id" : 111, "sku" : "qaz789", "description" : "Uou ke bi\nxxxxxxxx t ttttttt" }

... ]);

{

"acknowledged" : true,

"insertedIds" : [

     100,

     101,

     102,

     103,

     104,

     105,

     106,

     107,

     108,

     109,

     110,

     111

]

}

 

> db.regex.find();

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }

{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }

{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before     line" }

{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }

{ "_id" : 104, "sku" : "lmn123", "description" : "Farley\nI Love you!!!" }

{ "_id" : 105, "sku" : "lmn456", "description" : "Liuling keshimiershan" }

{ "_id" : 106, "sku" : "lmn789", "description" : "LiuFeng\ngugu dddxxxxxxxx" }

{ "_id" : 107, "sku" : "opq123", "description" : "XiongHui\nyour are a dog" }

{ "_id" : 108, "sku" : "opq456", "description" : "Maomaoyu xia si ni mei shangliang" }

{ "_id" : 109, "sku" : "opq789", "description" : "Gaofeng\ndu du a du,ni you are" }

{ "_id" : 110, "sku" : "qaz456", "description" : "Kebi\n da xiong mao siye" }

{ "_id" : 111, "sku" : "qaz789", "description" : "Uou ke bi\nxxxxxxxx t ttttttt" }

 

      1. 修改表名

> db.regex.renameCollection("products");

{ "ok" : 1 }

> db.regex.find();

> db.products.find();

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }

{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }

{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before     line" }

{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }

{ "_id" : 104, "sku" : "lmn123", "description" : "Farley\nI Love you!!!" }

{ "_id" : 105, "sku" : "lmn456", "description" : "Liuling keshimiershan" }

{ "_id" : 106, "sku" : "lmn789", "description" : "LiuFeng\ngugu dddxxxxxxxx" }

{ "_id" : 107, "sku" : "opq123", "description" : "XiongHui\nyour are a dog" }

{ "_id" : 108, "sku" : "opq456", "description" : "Maomaoyu xia si ni mei shangliang" }

{ "_id" : 109, "sku" : "opq789", "description" : "Gaofeng\ndu du a du,ni you are" }

{ "_id" : 110, "sku" : "qaz456", "description" : "Kebi\n da xiong mao siye" }

{ "_id" : 111, "sku" : "qaz789", "description" : "Uou ke bi\nxxxxxxxx t ttttttt" }

 

      1. Perform a LIKE Match

The following example matches all documents where the sku field is like "%789":

 

> db.products.find( { sku: { $regex: /789$/ } } )

{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }

{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }

{ "_id" : 106, "sku" : "lmn789", "description" : "LiuFeng\ngugu dddxxxxxxxx" }

{ "_id" : 109, "sku" : "opq789", "description" : "Gaofeng\ndu du a du,ni you are" }

{ "_id" : 111, "sku" : "qaz789", "description" : "Uou ke bi\nxxxxxxxx t ttttttt" }

 

      1. Perform Case-Insensitive Regular Expression Match

The following example uses the i option perform a case-insensitive match for documents with sku value that starts with ABC.

 

l i  大小写不敏感

 

> db.products.find( { sku: { $regex: /^ABC/i } } )

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }

{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }

 

> db.products.find( { sku: { $regex: /^ABC/ } } )

> db.products.find( { sku: { $regex: /^abc/ } } )

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }

{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }

 

      1. Multiline Match for Lines Starting with Specified Pattern

The following example uses the m option to match lines starting with the letter S for multiline strings:

 

db.products.find( { description: { $regex: /^S/, $options: 'm' } } )

 

> db.products.find( { description: { $regex: /^S/, $options: 'm' } } )

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }

{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }

 

如下这样对比还是有效果的:

> db.products.find( { description: { $regex: /^S/, $options: 'x' } } )

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }

> db.products.find( { description: { $regex: /^S/, $options: 'm' } } )

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }

{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }

  1. 还确实是获取到了多行的结果

 

再看如下结果:

> db.products.find( { description: { $regex: /^S/ } } )

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }

> db.products.find( { description: { $regex: /S/ } } )

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }

{ "_id" : 101, "sku" : "abc789", "description" : "First line\nSecond line" }

 

      1. Use the . Dot Character to Match New Line

The following example uses the s option to allow the dot character (i.e. .) to match all characters including new line as well as the i option to perform a case-insensitive match:

 

> db.products.find( { description: { $regex: /m.*line/, $options: 'i' } } )

{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before     line" }

> db.products.find( { description: { $regex: /m.*line/, $options: 'si' } } )

{ "_id" : 102, "sku" : "xyz456", "description" : "Many spaces before     line" }

{ "_id" : 103, "sku" : "xyz789", "description" : "Multiple\nline description" }

  1. 注意观察s的作用

 

      1. Ignore White Spaces in Pattern

The following example uses the x option ignore white spaces and the comments, denoted by the # and ending with the \n in the matching pattern:

 

> var pattern = "abc #category code\n123 #item number"

> db.products.find( { sku: { $regex: pattern, $options: "x" } } )

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }

> db.products.find( { sku: { $regex: pattern, $options: "m" } } )

> db.products.find( { sku: { $regex: pattern, $options: "i" } } )

> db.products.find( { sku: { $regex: pattern, $options: "ix" } } )

{ "_id" : 100, "sku" : "abc123", "description" : "Single line description." }

var pattern = "abc #category code\n123 #item number" 其中的#号为注释项;

其实内容仅:var pattern = "abc \n123 "

加了x后,匹配了sku的内容;

 

  1. Query on Embedded/Nested Documents
    1. Match an Embedded/Nested Document

> db.inventory.find( { size: { h: 14, w: 21, uom: "cm" } } )

{ "_id" : ObjectId("5bcd404ccfe6723a348dce06"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }

 

    1. Query on Nested Field
      1. Specify Equality Match on a Nested Field

> db.inventory.find( { "size.uom": "in" } )

{ "_id" : ObjectId("5bcd404ccfe6723a348dce07"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce08"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }

{ "_id" : ObjectId("5bcd47afcfe6723a348dce0c"), "item" : "bicycle", "qty" : 60, "size" : { "h" : 43.5, "w" : 111, "uom" : "in" }, "status" : "C" }

{ "_id" : ObjectId("5bcd47afcfe6723a348dce0e"), "item" : "friend", "qty" : 55, "size" : { "h" : 33.95, "w" : 180, "uom" : "in" }, "status" : "B" }

 

      1. Specify Match using Query Operator

> db.inventory.find( { "size.h": { $lt: 15 } } )

{ "_id" : ObjectId("5bcd404ccfe6723a348dce06"), "item" : "journal", "qty" : 25, "size" : { "h" : 14, "w" : 21, "uom" : "cm" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce07"), "item" : "notebook", "qty" : 50, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "A" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce08"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }

{ "_id" : ObjectId("5bcd404ccfe6723a348dce0a"), "item" : "postcard", "qty" : 45, "size" : { "h" : 10, "w" : 15.25, "uom" : "cm" }, "status" : "A" }

 

      1. Specify AND Condition

> db.inventory.find( { "size.h": { $lt: 15 }, "size.uom": "in", status: "D" } )

{ "_id" : ObjectId("5bcd404ccfe6723a348dce08"), "item" : "paper", "qty" : 100, "size" : { "h" : 8.5, "w" : 11, "uom" : "in" }, "status" : "D" }

 

  1. Query an Array
    1. 数据准备

db.array.insertMany([

   { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },

   { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },

   { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },

   { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },

   { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }

]);

 

> db.array.insertMany([

...    { item: "journal", qty: 25, tags: ["blank", "red"], dim_cm: [ 14, 21 ] },

...    { item: "notebook", qty: 50, tags: ["red", "blank"], dim_cm: [ 14, 21 ] },

...    { item: "paper", qty: 100, tags: ["red", "blank", "plain"], dim_cm: [ 14, 21 ] },

...    { item: "planner", qty: 75, tags: ["blank", "red"], dim_cm: [ 22.85, 30 ] },

...    { item: "postcard", qty: 45, tags: ["blue"], dim_cm: [ 10, 15.25 ] }

... ]);

{

"acknowledged" : true,

"insertedIds" : [

     ObjectId("5bcd8c5acfe6723a348dce10"),

     ObjectId("5bcd8c5acfe6723a348dce11"),

     ObjectId("5bcd8c5acfe6723a348dce12"),

     ObjectId("5bcd8c5acfe6723a348dce13"),

     ObjectId("5bcd8c5acfe6723a348dce14")

]

}

 

> db.array.find();

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce10"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce11"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce12"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce13"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce14"), "item" : "postcard", "qty" : 45, "tags" : [ "blue" ], "dim_cm" : [ 10, 15.25 ] }

 

    1. Match an Array

To specify equality condition on an array, use the query document { <field>: <value> } where <value> is the exact array to match, including the order of the elements.

 

The following example queries for all documents where the field tags value is an array with exactly two elements, "red" and "blank", in the specified order:

 

> db.array.find( { tags: ["red", "blank"] } )

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce11"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }

 

If, instead, you wish to find an array that contains both the elements "red" and "blank", without regard to order or other elements in the array, use the $all operator:

 

> db.array.find( { tags: { $all: ["red", "blank"] } } )

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce10"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce11"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce12"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce13"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }

 

    1. Query an Array for an Element

To query if the array field contains at least one element with the specified value, use the filter { <field>: <value> } where <value> is the element value.

 

The following example queries for all documents where tags is an array that contains the string "red" as one of its elements:

 

> db.array.find( { tags: "red" } )

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce10"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce11"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce12"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce13"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }

 

To specify conditions on the elements in the array field, use query operators in the query filter document:

{ <array field>: { <operator1>: <value1>, ... } }

 

For example, the following operation queries for all documents where the array dim_cm contains at least one element whose value is greater than 25.

db.inventory.find( { dim_cm: { $gt: 25 } } )

 

    1. Specify Multiple Conditions for Array Elements

When specifying compound conditions on array elements, you can specify the query such that either a single array element meets these condition or any combination of array elements meets the conditions.

      1. Query an Array with Compound Filter Conditions on the Array Elements

The following example queries for documents where the dim_cm array contains elements that in some combination satisfy the query conditions; e.g., one element can satisfy the greater than 15 condition and another element can satisfy the less than 20 condition, or a single element can satisfy both:

 

> db.array.find( { dim_cm: { $gt: 15, $lt: 20 } } )

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce10"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce11"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce12"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce14"), "item" : "postcard", "qty" : 45, "tags" : [ "blue" ], "dim_cm" : [ 10, 15.25 ] }

 

      1. Query for an Array Element that Meets Multiple Criteria

Use $elemMatch operator to specify multiple criteria on the elements of an array such that at least one array element satisfies all the specified criteria.

 

The following example queries for documents where the dim_cm array contains at least one element that is both greater than ($gt) 22 and less than ($lt) 30:

 

> db.array.find( { dim_cm: { $elemMatch: { $gt: 22, $lt: 30 } } } )

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce13"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }

  1. $elemMatch 专门用于一个元素符合多个条件

 

      1. Query for an Element by the Array Index Position

Using dot notation, you can specify query conditions for an element at a particular index or position of the array. The array uses zero-based indexing.

  1. NOTE
  2. When querying using dot notation, the field and nested field must be inside quotation marks.
  3. Index从0开始

 

The following example queries for all documents where the second element in the array dim_cm is greater than 25:

 

> db.array.find( { "dim_cm.1": { $gt: 25 } } )

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce13"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }

> db.array.find( { "dim_cm.0": { $gt: 25 } } )

 

> db.array.find( { "dim_cm.0": { $lt: 25 } } )

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce10"), "item" : "journal", "qty" : 25, "tags" : [ "blank", "red" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce11"), "item" : "notebook", "qty" : 50, "tags" : [ "red", "blank" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce12"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce13"), "item" : "planner", "qty" : 75, "tags" : [ "blank", "red" ], "dim_cm" : [ 22.85, 30 ] }

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce14"), "item" : "postcard", "qty" : 45, "tags" : [ "blue" ], "dim_cm" : [ 10, 15.25 ] }

 

> db.array.find( { "dim_cm.2": { $lt: 25 } } )

> db.array.find( { "dim_cm.20": { $lt: 25 } } )

 

      1. Query an Array by Array Length

Use the $size operator to query for arrays by number of elements. For example, the following selects documents where the array tags has 3 elements.

 

> db.array.find( { "tags": { $size: 3 } } )

{ "_id" : ObjectId("5bcd8c5acfe6723a348dce12"), "item" : "paper", "qty" : 100, "tags" : [ "red", "blank", "plain" ], "dim_cm" : [ 14, 21 ] }

 

  1. Query an Array of Embedded Documents
    1. 数据准备

db.stock.insertMany( [

   { item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },

   { item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },

   { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] },

   { item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },

   { item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }

]);

 

> db.stock.insertMany( [

...    { item: "journal", instock: [ { warehouse: "A", qty: 5 }, { warehouse: "C", qty: 15 } ] },

...    { item: "notebook", instock: [ { warehouse: "C", qty: 5 } ] },

...    { item: "paper", instock: [ { warehouse: "A", qty: 60 }, { warehouse: "B", qty: 15 } ] },

...    { item: "planner", instock: [ { warehouse: "A", qty: 40 }, { warehouse: "B", qty: 5 } ] },

...    { item: "postcard", instock: [ { warehouse: "B", qty: 15 }, { warehouse: "C", qty: 35 } ] }

... ]);

{

"acknowledged" : true,

"insertedIds" : [

     ObjectId("5bcd9f3bb09afd6021567a4b"),

     ObjectId("5bcd9f3bb09afd6021567a4c"),

     ObjectId("5bcd9f3bb09afd6021567a4d"),

     ObjectId("5bcd9f3bb09afd6021567a4e"),

     ObjectId("5bcd9f3bb09afd6021567a4f")

]

}

 

> db.stock.find();

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4b"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4c"), "item" : "notebook", "instock" : [ { "warehouse" : "C", "qty" : 5 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4d"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4e"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4f"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }

 

    1. Query for a Document Nested in an Array

The following example selects all documents where an element in the instock array matches the specified document:

 

> db.stock.find( { "instock": { warehouse: "A", qty: 5 } } )

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4b"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

 

Equality matches on the whole embedded/nested document require an exact match of the specified document, including the field order. For example, the following query does not match any documents in the inventory collection:

 

    1. Specify a Query Condition on a Field in an Array of Documents
      1. Specify a Query Condition on a Field Embedded in an Array of Documents

If you do not know the index position of the document nested in the array, concatenate the name of the array field, with a dot (.) and the name of the field in the nested document.

 

The following example selects all documents where the instock array has at least one embedded document that contains the field qty whose value is less than or equal to 20:

 

> db.stock.find( { 'instock.qty': { $lte: 20 } } )

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4b"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4c"), "item" : "notebook", "instock" : [ { "warehouse" : "C", "qty" : 5 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4d"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4e"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4f"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }

 

> db.stock.find( { 'instock.qty': { $lte: 10 } } )

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4b"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4c"), "item" : "notebook", "instock" : [ { "warehouse" : "C", "qty" : 5 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4e"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }

 

      1. Use the Array Index to Query for a Field in the Embedded Document

Using dot notation, you can specify query conditions for field in a document at a particular index or position of the array. The array uses zero-based indexing.

 

  1. NOTE
  2. When querying using dot notation, the field and index must be inside quotation marks.

 

The following example selects all documents where the instock array has as its first element a document that contains the field qty whose value is less than or equal to 20:

> db.stock.find( { 'instock.0.qty': { $lte: 20 } } )

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4b"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4c"), "item" : "notebook", "instock" : [ { "warehouse" : "C", "qty" : 5 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4f"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }

 

    1. Specify Multiple Conditions for Array of Documents

When specifying conditions on more than one field nested in an array of documents, you can specify the query such that either a single document meets these condition or any combination of documents (including a single document) in the array meets the conditions.

      1. A Single Nested Document Meets Multiple Query Conditions on Nested Fields

Use $elemMatch operator to specify multiple criteria on an array of embedded documents such that at least one embedded document satisfies all the specified criteria.

 

The following example queries for documents where the instock array has at least one embedded document that contains both the field qty equal to 5 and the field warehouse equal to A:

 

> db.stock.find( { "instock": { $elemMatch: { qty: 5, warehouse: "A" } } } )

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4b"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

 

The following example queries for documents where the instock array has at least one embedded document that contains the field qty that is greater than 10 and less than or equal to 20:

 

> db.stock.find( { "instock": { $elemMatch: { qty: { $gt: 10, $lte: 20 } } } } )

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4b"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4d"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4f"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }

 

      1. Combination of Elements Satisfies the Criteria

If the compound query conditions on an array field do not use the $elemMatch operator, the query selects those documents whose array contains any combination of elements that satisfies the conditions.

 

For example, the following query matches documents where any document nested in the instock array has the qty field greater than 10 and any document (but not necessarily the same embedded document) in the array has the qty field less than or equal to 20:

 

> db.stock.find( { "instock.qty": { $gt: 10,  $lte: 20 } } )

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4b"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4d"), "item" : "paper", "instock" : [ { "warehouse" : "A", "qty" : 60 }, { "warehouse" : "B", "qty" : 15 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4e"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4f"), "item" : "postcard", "instock" : [ { "warehouse" : "B", "qty" : 15 }, { "warehouse" : "C", "qty" : 35 } ] }

 

The following example queries for documents where the instock array has at least one embedded document that contains the field qty equal to 5 and at least one embedded document (but not necessarily the same embedded document) that contains the field warehouse equal to A:

 

> db.stock.find( { "instock.qty": 5, "instock.warehouse": "A" } )

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4b"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4e"), "item" : "planner", "instock" : [ { "warehouse" : "A", "qty" : 40 }, { "warehouse" : "B", "qty" : 5 } ] }

 

> db.stock.find( {"instock": {$elemMatch: { "qty": 5, "warehouse": "A" }}} )

{ "_id" : ObjectId("5bcd9f3bb09afd6021567a4b"), "item" : "journal", "instock" : [ { "warehouse" : "A", "qty" : 5 }, { "warehouse" : "C", "qty" : 15 } ] }

 

猜你喜欢

转载自blog.csdn.net/it_monkey_ali/article/details/83345205
今日推荐