Write concern is a balance between response time(performance) and the success of a write operation(Reliability). Write includes insert, udpate and delete. A weak write concern: write operations return quickly, but data maybe not persist well(including replica set). A strong write concern: clients wait after mongodb confirm the write operation suncessful.
Levels
listed from weakest to strongest
Unacknowledged {W:0}
similar to errors ignored
Acknowledged {W:1} used in writing unimportant data, e.g. some operation log, user’s behavior(click, time staying in one page)
default write concern the mongod confirms that it received the write operation and applied the change to the in-memory view of data allows clients to catch network, duplicate key, and other errors does not confirm that the write operation has persisted to the disk system
Journaled {w:1,j:true} used in writing key, business data, e.g. order, account
committing the data to the journal(journaling enabled first) ensures that MongoDB can recover the data following a shutdown or power interruption
Replica Acknowledged {w:2}
guarantee write sucessfully to one Replica Set beside the primary
Timeouts
set at client side
wtimeout: in milliseconds
wtimeout causes write operations to return with an error after the specified limit, even if the required write concern will eventually succeed
MongoDB does not “rollback” or undo modifications made before the wtimeout interval expired
getLastError()
Driver implicitly and immediately call this method after one write operation depending on level of Write Corcern
1 2 3 4 5 6 7 8 9 10 11 12 13 14
//after insert(), implicitly call db.getLastError(); if capturing error, assign it to err of callback function. // when w:-1, err is always null // when w:0, except network error, normally no other error can be captured // when w:1, return error from mongod to err parameter db.collection("test", {}, function(err, collection) { collection.insert({ name: "world peace" }, function(err, result) { assert.equal(null, err); console.log(result); db.close(); }) });
//return all account documents with name "Strong" db.account.find({name:{$eq:"Strong"}}); //ruturn all accounts whose age are less than 18 db.account.find({age:{$lte:18}}); //Return all documents in the inventory collection where the quantity does not equal 5 nor 15 db.inventory.find({quantity:{$nin:[5, 15]}});
Logical Operator
Operator
JavaScript
Example
js Example
Description
$and
&&
{$and:[{},…{expressionN}]}
x < a && x > b
and, match the conditions of both clauses
$or
OR
{$or:[{},…{expressionN}]}
x < a OR x > b
or, match the conditions of either clause
$not
!
{$not:[{},…{expressionN}]}
!(x == y)
not, do not match the query expression
$nor
n/a
{$nor:[{},…{expressionN}]}
n/a
Joins query clauses with a logical NOR returns all documents that fail to match both clauses
NOTE: OR stands for || for js opeator above.
$and example
$and performs a logical AND operation on an array of two or more expressions and selects the documents that satisfy all the expressions in the array
1 2 3 4
//AND query with multiple expressions db.inventory.find({$and:[{price:{$ne:1.99}},{price:{$exists:true}}]}); //implicit AND operation db.inventory.find({price:{$ne:1.99,$exists:true}});
This query will select all documents in the inventory collection where:
the price field value is not equal to 1.99 and
the price field exists.
$nor example
1 2
//query with two expressions db.inventory.find({$nor:[{price:19.99},{isSale:true}]});
This query will return all documents that:
contain the price field whose value is not equal to 19.99 and contain the isSale field whose value is not equal to true or
contain the price field whose value is not equal to 19.99 but do not contain the isSale field or
do not contain the price field but contain the isSale field whose value is not equal to true or
do not contain the price field and do not contain the isSale field
Field Check Operator
$exists
Matches documents that have the specified field, {field: {$exists:boolean value}} . When boolean value is true, $exists matches the documents that contain the field, including documents where the field value is null. If boolean value is false, the query returns only the documents that do not contain the field.
$type selects the documents where the value of the field is an instance of the specified numeric BSON type.
1
db.collection.find({field:{$type:n});
NOTE:
n stands for numeric BSON type 1 for Double 2 for String 3 Object 4 Array 7 ObjectId 8 Boolean 9 Date 10 Null 11 Regular Expression 13 JavaScript 15 js with scope 16 32 bit integer 17 timestamp 18 64 bit integer 255 Min key(but query with -1) 127 Max key
Operator for Array
$all
Match arrays that contain all elements specified in the query Like SQL’s in operator, the difference is that $all must match all values within [], but in can only match any one value within (). {field:{$all:[value1, … valueN]}}
// db.accounts.find({age : {$all : [16, 17]}}); // {name: 'Jobs', age: 26, age: [ 16, 18, 19 ] } : can't match // {name: 'Bill', age: 26, age: [ 16, 17, 19 ] } : match ###elemMatch The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria. > Format: { <field>: { $elemMatch: { <q1>, <q2>, ... } } } It does not need touse $elemMatch operator for single query condition
$where provides flexibility use the $where operator to pass either a string containing a JavaScript expression or a full JavaScript function to the query system cannot take advantage of indexes
different expression, same result
1 2 3 4 5 6 7
db.employee.find({age:{$gt:35}}); //Reference the document in the JavaScript expression or function using either **this** or **obj** db.employee.find({$where:"this.age > 35"}); db.employee.find("this.age>35");
Thought: use “user story” with acceptance criteria is a best practice in scrum process, no one use “use case”.
User story
lightweight
a short description of something that can be written on a card, focused on the value or result they get from doing this thing Format: As an [actor] I want [action] so that [achievement] A User Story doesn’t capture all the details, it’s an informal support for the discussion.
Acceptance criteria
Writing the acceptance criteria is the first step of fleshing out the details of your user story.
define the boundaries of a user story, and are used to confirm when a story is completed and working as intended
example
As a conference attendee, I want to be able to register online, so I can register quickly and cut down on paperwork, the acceptance criteria could include:
A user cannot submit a form without completing all the mandatory fields
Information from the form is stored in the registrations database
Protection against spam is working
Payment can be made via credit card
An acknowledgment email is sent to the user after submitting the form.
Use case
heavyweight use case describes a “Normal Flow” of steps and/or actions and “Alternative Flows” which are detailed.
formal specification, usually created as a formal document, detail description of a set of interactions between a system and and one or more roles, roles can be people or systems, including something as below,
Use case title
Rationale/description/goal
Actor/user
Preconditions (the things that must have already happened in the system)
Standard path or Main success scenario (what will usually happen, described as a series of steps)
Alternate paths or Extensions(variations on the above/edge cases)
Post conditions (what the system will have done by the end of the steps).
Team work is a must practice to achieve a big software developing goal today, there are many people involved in same project, a bunch of tools make good cooperation, better communication,
Infrastructure support: ESB, MQ, …
projecct management, scheoudule, execution
engineering process tool
requirement specification: trace change
design document
IDE: VS Studio, sublime, webstorm, text editor,
testing case
software quality tools
maintenanec - refactor, re-engineering
Configurationn and deployment tools
modern communication tool: email, live meeting, screen share,..
Tips: retrieve previous commands issued in shell with up or down arrow key (Windows something like, C:\Users\myaccount.dbshell)
Start Shell
1 2 3 4 5 6 7
//start shell without connection to a database mongo --nodb
//execute js file mongo localhost:27017/testDB file.js //alternative use load function n the shell load("file.js") // execute js, file.js located on "data" directory
use <db_name> // switch current db to db_name show dbs / databases // list all databases on server show collections / tables // list all tables on current db db or db.getName) // show current db in shell // show roles // list all roles of current db show users // list all users of current db show profile //how to get command reference in the shell help or db.help() or db.collection.help() //database can created automatically when saving data to MongoDB in shell //Delete a database db.dropDatabase() //drop current dtabase, delete all associated files //Delete a collection db.collection.drop() //remove table and index //running in secure mode db.auth() //authenticate user // refer to another database using same connection db.getSiblingDB(); //without explicitly switch the current database
CRUD at mongo shell
Overview
1 2 3 4 5 6 7 8 9 10
table = db.myCollection; //table refer a specific collection table.find(); //return a cursor table.findOne(); //return a single document or null table.count(); //count of documents table.save(); //insert new or update existing document table.insert(); //insert new document table.update(); //update existing document table.remove(); //delete existing document //build index table.createIndex();
//Loop samples in shell use my //switch current db to my for( var i=1;i<=200;i++) db.my.save({tag:"number",val:i}); for( var i=201;i<=250;i++) db.my.save({tag:i}); //it command it //iterate cursor //Loop to return all var cursor = db.my.find(); //method I while( cursor.hasNext()) { printjson(cursor.next()); } //method II cursor.forEach(printjson); //method III var myArray = db.my.find().toArray(); printjson(myArray[2]); //update db.my.update({val:6},{$set:{tag:"NUMBER"}}); // to very update db.my.find().limit(20);
Query
1 2 3 4 5 6 7
//SQL: select tag, val from my where tag = "number" db.my.find({tag:"number"}).count(); db.my.find({tag:"number"},{val:true,tag:true}).limit(16); db.my.findOne({tag:"number"},{val:true}); db.my.find({tag:"number"},{val:true,tag:true}).forEach(printjson); //SQL: select * from my where tag > 200 db.my.find({tag:{$gt:200}}).forEach(printjson);
Delete
1 2 3 4
//remove() function db.my.remove({tag:"NUMBER"}); // to verify db.my.find().limit(20);