[Switch] MongoDB study notes (query)

  1. Basic query:
    Construct query data.

    > db.test.findOne()
    {
         "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"),
         "name" : "stephen",
         "age" : 35,
         "genda" : "male",
         "email" : "[email protected]"
    }

    --Multiple conditional query. The following example is equivalent to the SQL statement where name = "stephen" and age = 35

    > db.test.find({"name":"stephen","age":35})
    { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35, "genda" : "male", "email" : "[email protected]" }

    --Returns the specified document key-value pair. The example below will simply return the name and age key-value pair.

    > db.test.find({}, {"name":1,"age":1})
       { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35 }

    --Specify document key-value pairs not to be returned. The following example will return all key-value pairs except name.

    > db.test.find({}, {"name":0})
    { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "age" : 35, "genda" : "male", "email" : "[email protected]" }
  2. Query conditions:
    MongoDB provides a set of comparison operators: \(lt/\) lte/ \(gt/\) gte/ \(ne, which in turn are equivalent to </<=/>/>=/!=. - - The example below returns documents that match the condition age >= 18 && age <= 40. ``` > db.test.find({"age":{"\) gte":18, "$lte":40} })
    { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "[email protected] " }

    
    --下面的示例返回条件符合name != "stephen1"

    db.test.find({"name":{"$ne":"stephen1"}})
    { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "[email protected]" }

    
    --$in等同于SQL中的in,下面的示例等同于SQL中的in ("stephen","stephen1")

    db.test.find({"name":{"$in":["stephen","stephen1"]}})
    { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "[email protected]" }

    
    --和SQL不同的是,MongoDB的in list中的数据可以是不同类型。这种情况可用于不同类型的别名场景。

    db.test.find({"name":{"$in":["stephen",123]}})
    { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "[email protected]" }

    
    --$nin等同于SQL中的not in,同时也是$in的取反。如:

    db.test.find({"name":{"$nin":["stephen2","stephen1"]}})
    { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "[email protected]" }

    
    --$or等同于SQL中的or,$or所针对的条件被放到一个数组中,每个数组元素表示or的一个条件。
    --下面的示例等同于name = "stephen1" or age = 35

    db.test.find({"$or": [{"name":"stephen1"}, {"age":35}]})
    { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "[email protected]" }

    
    --下面的示例演示了如何混合使用$or和$in。

    db.test.find({"\(or": [{"name":{"\)in":["stephen","stephen1"]}}, {"age":36}]})
    { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "[email protected]" }

    
    --$not表示取反,等同于SQL中的not。

    db.test.find({"name": {"\(not": {"\)in":["stephen2","stephen1"]}}})
    { "_id" : ObjectId("4fd58ecbb9ac507e96276f1a"), "name" : "stephen", "age" : 35,"genda" : "male", "email" : "[email protected]" }
    ```

  3. Null data type query:
    -- When performing a query with null data, all documents whose value is null and do not contain the specified key will be retrieved.

    > db.test.find({"x":null})
    { "_id" : ObjectId("4fd59d30b9ac507e96276f1b"), "x" : null }
    { "_id" : ObjectId("4fd59d49b9ac507e96276f1c"), "y" : 1 }

    --Need to use null as an element in the array for equality, even if there is only one element in the array.
    --And then there is the use of \(exists to determine whether the specified key exists. ``` > db.test.find({"x": {"\) in": [null], "$exists":true}})
    { "_id" : ObjectId("4fd59d30b9ac507e96276f1b"), "x" : null }
    ```

  4. Regular query:
    --MongoDB uses the regular syntax of Perl rules. Such as:

    > db.test.find()
    { "_id" : ObjectId("4fd59ed7b9ac507e96276f1d"), "name" : "stephen" }
    { "_id" : ObjectId("4fd59edbb9ac507e96276f1e"), "name" : "stephen1" }

    --i means ignore case

    > db.test.find({"name":/stephen?/i})
    { "_id" : ObjectId("4fd59ed7b9ac507e96276f1d"), "name" : "stephen" }
    { "_id" : ObjectId("4fd59edbb9ac507e96276f1e"), "name" : "stephen1" } 
  5. Array data query:
    -- Array-based lookup.

    > db.test.find()
    { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", "peach" ] }
    { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "apple", "kumquat","orange" ] }
    { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana","apple" ] }

    --All documents that contain banana in the array will be retrieved.

    > db.test.find({"fruit":"banana"})
    { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", "peach" ] }
    { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana","apple" ] }

    --If the retrieval array needs to contain multiple elements, use \(all here. In the following example, the array must contain both apple and banana, but their order does not matter. ``` > db.test.find( {"fruit": {"\) all": ["banana","apple"]}})
    { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", " peach" ] }
    { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana", "apple" ] }

    --下面的示例表示精确匹配,即被检索出来的文档,fruit值中的数组数据必须和查询条件完全匹配,即不能多,也不能少,顺序也必须保持一致。

    db.test.find({"fruit":["apple","banana","peach"]})
    { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", peach" ] }

    --下面的示例将匹配数组中指定下标元素的值。数组的起始下标是0。

    db.test.find({"fruit.2":"peach"})
    { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", peach" ] }

    --可以通过$size获取数组的长度,但是$size不能和比较操作符联合使用。

    db.test.find({"fruit": {$size : 3}})
    { "_id" : ObjectId("4fd5a177b9ac507e96276f1f"), "fruit" : [ "apple", "banana", "peach" ] }
    { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "apple", "kumquat","orange" ] }
    { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana","apple" ] }

    --如果需要检索size > n的结果,不能直接使用$size,只能是添加一个额外的键表示数据中的元素数据,在操作数据中的元素时,需要同时更新size键的值。
    --为后面的实验构造数据。

    db.test.update({}, {"$set": {"size":3}},false,true)
    db.test.find()
    { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "apple", "kumquat", "orange" ], "size" : 3 }
    { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana", "apple" ], "size" : 3 }

    --每次添加一个新元素,都要原子性的自增size一次。

    test.update({},{"\(push": {"fruit":"strawberry"},"\)inc":{"size":1}},false,true)
    db.test.find()
    { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "apple", "kumquat", "orange", "strawberry" ], "size" : 4 }
    { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana", "apple", "strawberry" ], "size" : 4 }

    --通过$slice返回数组中的部分数据。"$slice":2表示数组中的前两个元素。

    db.test.find({},{"fruit": {"$slice":2}, "size":0})
    { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "apple", "kumquat" ]}
    { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "cherry", "banana" ]}

    --通过$slice返回数组中的部分数据。"$slice":-2表示数组中的后两个元素。

    db.test.find({},{"fruit": {"$slice":-2}, "size":0})
    { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "orange", "strawberry" ] }
    { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "apple", "strawberry" ] }

    --$slice : [2,1],表示从第二个2元素开始取1个,如果获取数量大于2后面的元素数量,则取后面的全部数据。

    db.test.find({},{"fruit": {"$slice":[2,1]}, "size":0})
    { "_id" : ObjectId("4fd5a18cb9ac507e96276f20"), "fruit" : [ "orange" ] }
    { "_id" : ObjectId("4fd5a1f0b9ac507e96276f21"), "fruit" : [ "apple" ] }
    ```

  6. Inline document query:
    -- Construct test data for later examples.

    > db.test.find()
    { "_id" : ObjectId("4fd5ada3b9ac507e96276f22"), "name" : { "first" : "Joe", "last" : "He" }, "age" : 45 }

    --When the embedded document is an array, the \(elemMatch operator is required to help locate the matching situation of a certain element, otherwise the embedded document will be matched all. --That is, all elements need to be listed as a query when searching ``` > db.test.findOne() { "_id" : ObjectId("4fd5af76b9ac507e96276f23"), "comments" : [ { "author" : "joe", "score" : 3 }, { " author" : "mary", "score" : 6 } ] } > db.test.find({"comments": {"\) elemMatch": {"author":"joe","score":{"$ gte":3}}}}
    { "_id" : ObjectId("4fd5af76b9ac507e96276f23"), "comments" : [ { "author" : "joe", "score" : 3 }, { "author" : "mary", "score" : 6 } ] }
    ```

  7. Cursor:
    The database uses the cursor to return the execution result of find(). The client can effectively control the cursor, such as: limiting the number of result sets, skipping partial results, sorting in any direction based on any key, etc.
    The following example will be used to prepare test data.

    > db.testtable.remove()
    > for (i = 0; i < 10; ++i) {
    ... db.testtable.insert({x:i})
    ... }

    We can use the hasNext() method provided by the cursor to determine whether there is still unread data, and then use the next() method to read the next document in the result set. Such as:

    > var c = db.testtable.find()
    > while (c.hasNext()) {
    ... print(c.next().x)
    ... }

    When calling find(), the shell does not query the database immediately, but waits until it actually starts asking for results before sending the query, so that additional options can be attached to the query before execution. Almost all cursor methods return themselves, so it is possible to chain cursor methods as follows. Such as:

    > var c1 = db.testtable.find().sort({"x":1}).limit(1).skip(4);
    > var c2 = db.testtable.find().limit(1).sort({"x":1}).skip(4);
    > var c3 = db.testtable.find().skip(4).limit(1).sort({"x":1});

    At this point, the query is not executed, all these functions are constructing the query, when the following statement is executed, the query will be actually executed,

    > c.hasNext()

    The query is sent to the server, and the MongoDB server will return a batch of data each time. When the batch is fully iterated, the next batch of data will be read from the server until all the data required for the query result is iterated.

    For the above example, limit(1) means that there is only one output result, if it is less than 1, it will not output, that is, the limit(n) function limits the output result at most. skip(4) means to skip the first 4 documents in the query result, if the result is less than 4, no document will be returned. sort({"x":1}) is used to set the sorting conditions, that is, sort in ascending order (1) according to the x key. If you need to sort in descending order, you can change it to: sort({"x":-1}). sort can also support multi-key sorting, such as: sort({username:1, age:-1}), that is, sort by username in ascending order, and then sort by age key in descending order if the values ​​of username are the same. It should be pointed out here that if you skip too many documents, it will cause performance problems.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324861427&siteId=291194637