The Find () function in the
MongoDB returns a cursor that enables the client to effectively control the query results by setting some settings on the cursor, such as restricting the number of results obtained by the query, skipping partial results, or pressing any key to the result set. We used to operate in the shell, using the Find () function directly, without using its return value, such as:
> for (var i=0 i<100; i++) {... db.coll.insert ({"X": i});..} > Db.coll.find ();
{"_id": ObjectId ("5023997e1ed370450fbdcf89"), "X": 25}
{"_id": ObjectId ("5023997e1ed370450fbdcf8a"), "X": 26}
{"_id": ObjectId ("5023997e1ed370450fbdcf8b"), "X": 27}
{"_id": ObjectId ("5023997e1ed370450fbdcf8c"), "X": 28}
{"_id": ObjectId ("5023997e1ed370450fbdcf8d"), "X": 29}
{"_id": ObjectId ("5023997e1ed370450fbdcf8e"), "X": 30}
{"_id": ObjectId ("5023997e1ed370450fbdcf8f"), "X": 31}
{"_id": ObjectId ("5023997e1ed370450fbdcf90"), "X": 32}
{"_id": ObjectId ("5023997e1ed370450fbdcf91"), "X": 33}
{"_id": ObjectId ("5023997e1ed370450fbdcf92"), "X": 34}
{"_id": ObjectId ("5023997e1ed370450fbdcf93"), "X": 35}
{"_id": ObjectId ("5023997e1ed370450fbdcf94"), "X": 36}
{"_id": ObjectId ("5023997e1ed370450fbdcf95"), "X": 37}
{"_id": ObjectId ("5023997e1ed370450fbdcf96"), "X": 38}
{"_id": ObjectId ("5023997e1ed370450fbdcf97"), "X": 39} {"_id": ObjectId ("5023997e1ed370450fbdcf98 ")," X ": {" _id ": ObjectId (" 5023997e1ed370450fbdcf99 ")," X ": 5023997} {" _id ": ObjectId e1ed370450fbdcf9a ")," X ": {" _id ": ObjectId (" 5023997e1ed370450fbdcf9b ")," X ": {" _id ": ObjectId (" 5023997e1ed 370450fbdcf9c ")," X ": Has more >
We first populate the collection with JavaScript script 100 documents and call the Find function directly. It automatically recursively returns the cursor returned by find, displaying the first 20 data in the shell. If we keep the return value of the Find function through a variable, it does not automatically traverse the display:
> var cursor = db.coll.find ();
>
In doing so, what actually happens is that after the call is done, the shell does not actually access the database, but rather waits for the result to be started before sending a query request to the database. We can then make a variety of settings for this cursor and then call the cursor's hashnext () or Next () method, which will actually access the database, which is a lazy loading process. As follows:
> var cursor = db.coll.find ();
> while (Cursor.hasnext ()) {
... var doc = Cursor.next ();
...//do stuff with Doc
...};
>
In the code above, when Cursor.hasnext () is invoked, the query is sent to the database, and by default returns the first 100 documents or the first 4M of data (the smaller of both) so that next or hasnext are called locally. When this set of data is traversed, Hasnext will cause the database to be accessed again until all the results are returned.
"Operation of the cursor"
As mentioned above, when we get the cursor, we can deal with the cursor first, then let the access to the database occur as we wish. Here are 3 functions that can be used when processing cursors: limit, skip, sort. Limit is the limit of the number of cursors returned, the upper limit is specified, skip is to ignore the previous part of the document, if the total number of documents is less than the ignored quantity, then return the empty collection, sort the resulting subset of the order, you can follow the multiple keys to order. The trick to manipulating a cursor is that the function that operates the cursor returns a cursor, so you can make a method chain call, as follows:
> Db.fruitprice.find (); {"_id": ObjectId ("50226b4c3becfacce6a22a5b"), "apple": "Banana": 6, "Pear": 3} {"_id": ObjectId ("50226BA63BECF Acce6a22a5c ")," apple ":" Watermelon ": 3," Pear ": 3} {" _id ": ObjectId (" 5023a1db7dceac1a6dacb0b7 ")," Apple ": 8," Orange ": 4," Tomato ": 3} {" _id ": ObjectId (" 5023a1eb7dceac1a6dacb0b8 ")," Apple ": 9," Orange ": 5," Grape ": 12} {" _ ID ": ObjectId (" 5023a2037dceac1a6dacb0b9 ")," melon ": 7," Orange ": 3," Grape ": one} > Db.fruitprice.find (). Sort ({" app
Le ": 1," banana ":-1});
{"_id": ObjectId ("5023a2037dceac1a6dacb0b9"), "melon": 7, "Orange": 3, "Grape": 11} {"_id": ObjectId ("5023a1db7dceac1a6dacb0b7"), "Apple": 8, "Orange": 4, "Tomato": 3} {"_id": ObjectId ("5023a1eb7dce Ac1a6dacb0b8 ")," Apple ": 9," Orange ": 5," grape ": {" _id ": ObjectId (" 50226b4c3becfacce6a22a5b ")," Apple ":" B " Anana ": 6," Pear ": 3} {" _id ": ObjectId (" 50226ba63becfacce6a22a5c ")," apple ": Ten," Watermelon ": 3," Pear ": 3} > Db.fruItprice.find (). Skip (1). Limit (3). Sort ({"Apple": 1, "banana":-1}); {"_id": ObjectId ("5023a1db7dceac1a6dacb0b7"), "Apple": 8, "Orange": 4, "Tomato": 3} {"_id": ObjectId ("5023a1eb7dce Ac1a6dacb0b8 ")," Apple ": 9," Orange ": 5," grape ": {" _id ": ObjectId (" 50226b4c3becfacce6a22a5b ")," Apple ":" B " Anana ": 6," Pear ": 3} >
Above, a total of 3 queries were executed:
Only the Find function was executed for the first time, and a collection was returned with no order.
The second time, we let it sort by the key "Apple" key "banana", the key "Apple" in ascending order (>0 number), the key "banana" descending (<0 number), that is, first press the key "Apple" ascending row, for the key "Apple" is equal to the document, the key "" Banana the descending row. We see that in this way the documents without the key "Apple" (that is, the key "Apple" value is null) are in the first place, which is in MongoDB, with a default order for different types of values for the same key, which we'll mention later.
For the third time, we used three functions to set the cursor. The relationship between these three functions is that, on the database server side, the sort is executed first and then the order is performed on the document, and the final subset of the document is returned according to the maximum number set by limit.
"Comparison order for different types of values of the same key"
When sorting by key, the MongoDB does not enforce the value of the key, and we also encounter the same key in practice, in which a string is a number in another document, and the document is sorted in any way. In MongoDB, there is a predefined order, from small to large, followed by:
(1): Minimum value
(2): null
(3): Digital (integral type, long integer, double precision)
(4): string
(5): Objects/Documents
(6): Array
(7): Binary data
(8): Object ID
(9): Boolean value
(10): Date type
(11): Time stamp
(12): Regular expressions
(13): Maximum value
In the second type of query mentioned above, we press "Apple" to check that the key is missing from a document in which the value of the key is null, and in other documents the value of the key is a number, and in this order, the document that is missing the key should be in the front of the ascending row.
"Avoid skipping a lot of results with skip"
Using skip for a small amount of document efficiency will not have any effect, and if you skip over a large number of results, you may have a performance bottleneck. For Skip, our usual application might be when paging. For pagination, there are two ways to respond:
1. Put the processing of pagination in the application layer, the data are all detected, and then the application layer to process the paging display. This is what is commonly called pseudo paging.
2. If paging must be done at the database end, this is usually a case of too much data. At this point, we first try to use the skip operation, if there is a performance bottleneck, we can only according to a sort key, in the acquisition of the next page of data, first of the last document in the previous page of the value of the key to query the document, the last order to intercept. This avoids the use of skip.
"Advanced query Options"
The query is divided into ordinary query and packaging query, we demonstrated above all kinds of query methods are ordinary query, as follows we will demonstrate a:
> Db.fruitprice.find ({"Apple":}). sort ({"Banana": 1});
{"_id": ObjectId ("50226ba63becfacce6a22a5c"), "apple": Ten, "Watermelon": 3, "Pear": 3}
{"_id": ObjectId ("50226b4c3becfacce6a22a5b"), "apple": Ten, "banana": 6, "Pear": 3}
>
The above query we converted to the form of packaging is:
> Db.fruitprice.find ({"$query": {"Apple": Ten}, "$orderby": {"banana": 1}});
{"_id": ObjectId ("50226ba63becfacce6a22a5c"), "apple": Ten, "Watermelon": 3, "Pear": 3}
{"_id": ObjectId ("50226b4c3becfacce6a22a5b"), "apple": Ten, "banana": 6, "Pear": 3}
>
All of our queries are converted to the wrapper form in advance when they are sent to the database end. The form of packaging is the extra use of some keys, such as the "$query", "$orderby". We also have some of the following useful keys available:
1. $maxscan: integer Specify the maximum number of documents scanned when querying
2. $min: Start condition of document query
3. $max: End condition of document query
4. $hint: document Specifies which indexes the server uses to query
5. $explain: Boolean Gets the details of the query, such as the index used, the number of results, time-consuming, and so on, similar to view the execution plan on the relational database side. Does not actually execute the query
6. $snapshot: Boolean ensures that the result of the query is a consistent snapshot at the moment the query executes. This will also be mentioned later.
"Get consistent results"
When we get the data from the MongoDB, we usually do this: once the document is processed, it is immediately updated to the database. There is a problem with a large number of documents, and let me describe: As mentioned earlier, when we call the Hasnext of a cursor from the database side, the database returns 100 documents to us by default, and we start the operation. Suppose we increase the size of a document and MongoDB the reserved area for the document, when we update the document to the database, the database is unable to place it in its original location and can only move it, usually moving to the end of the collection. So when we get the document again, it's possible to get the document that was modified again ...
To deal with this problem, our approach is to snapshot the results of the query. If the "$snapshop" option mentioned above is used, the query is run against the Invariant collection view. This is just a description of the fact that you don't have to worry about it, because in MongoDB, all the queries that return a group actually take a snapshot.