Truy Vấn Mongodb Cơ Bản

Ở bài viết trước mình cùng các bạn đã tìm hiểu qua cách cài đặt cũng như khắc phục một số lỗi cơ bản khi làm việc với mongodb trên môi trường linux. Ở bài viêt này mình sẽ cùng các bạn đi qua một số câu lệnh cơ bản trong mongodb và đi kèm theo nó là một số ví dụ trực quan. Danh mục mình sẽ đề cập đến trong bài viết này được tóm gọn qua 2 phần
  1. Tổng hợp một số lệnh truy vấn
  2. Một số lệnh truy vấn riêng biệt

1. Tổng hợp một số lệnh truy vấn

a. Truy vấn so sánh
  • $eq: so sánh bằng tương đương với lệnh so find thông thường của 1 field
                    Ví dụ: {<field>: {$eq: <value>}} ó {field: <value>}.
  • $gt : So sánh lớn hơn
  • $gte: So sánh lớn hơn hoặc bằng
  • $lt: So sánh nhỏ hơn
  • $lte: So sánh nhỏ hơn hoặc bằng
  • $ne (not equal): Trả ra tất cả các giá trị không thỏa điều kiện này
  • $in : Trả ra tất cả các giá trị khớp trong 1 danh sách mảng
  • $nin: Trả ra tất cả các giá trị không khớp trong 1 danh sách mảng
b. Truy vấn logic
  • $or: join các lệnh truy vấn cùng với điều kiện hoặc,, lấy tất cả giá trị thỏa mã điều kiện or nhu tư duy lập trình thông thường, param cũng là 1 array và lấy field làm param
                   { $or: [ { <expression1> }, { <expression2> }, ... , { <expressionN> } ] }
  • $and: trả về kết quả thỏa mãn hết các điều kiện, parram là 1 array và lấy field làm param
                  { $and: [ { <expression1> }, { <expression2> } , ... , { <expressionN> } ] }
  • $not: trả về kết quả không thỏa mãn các điều kiện truyền vào, lưu ý param ở đây chỉ là 1 field
                 {field: { $not: { <operator-expression> } } }
  • $nor: trả về kết quả không thỏa mãn các điều kiện truyền vào, khác với not là nor có param là 1 array và lấy field làm param.
                 {$nor: [ { <expression1> }, { <expression2> }, ...  { <expressionN> } ] }
c. Truy vấn thành phần
  • $exists: Trả về kết quả nếu field đấy tồn tại, là param của field
                Vd: db.inventory.find( { qty: { $exists: true, $nin: [ 5, 15 ] } } )
d. Truy vấn đánh giá
  • $mod: lấy ra tập các dữ liệu mà giá trị của các trường chia hết bởi số chia và số còn lại
              {field: {$mod: [ divisor, remainder ]}}
                    Vd: db.inventory.find( { qty: { $mod: [ 4, 0 ] } } ) … Tìm tài liệu của qty mà giá trị của qty chia cho 4 dư 0
  • $regex: tìm kiếm so khớp theo mẫu pattern
  • $text: query data với data unicode. Cụ thể ở đây ta sẽ query được data chứa dấu Tiếng Việt. Mình sẽ đề cập tới truy vấn này trong một bài viết gần nhất của danh mục này
  • $where: Điều kiện truy vấn, toán tử where giúp ta liên tưởng tới toán từ where trong SQL
e. Các bộ filter kết hợp
  • sort: Lọc 1 bộ giá trị vd db.teacher.find().sort({age:1, exp: -1})  ó lọc tuổi theo thứ tự tăng dần còn số năm kinh nghiệm (exp) giảm dần
  • limit: Giới hạn số lượng phần tử hiển thị vd: limit(4) => hiển thị 4 phần tử.
  • Count: đếm số phần tử trong kết quả tìm kiếm trả về vd: 
    • db.teacher.find({name: {$not: /^[Mm]\w+/ }}).count()
          Chỉ định phần tử hiển thị và không hiển thị: Nghĩa là khi tìm kiếm bạn chỉ muốn kết quả trả ra các field mong  muốn hay hủy đi các field không mong muốn  => Ta sử dụng 0 (hủy đi) --- và 1 (hiển thị): Ví dụ:
         db.teacher.find({}, {"name":1, age:1}) => chỉ hiển thị name và age
         db.teacher.find({}, {"name":0, age:0}) => hiển thị tất cả các field ngoại trừ field name và age
Chú ý: Không thể kết hợp 2 điều kiện 0 và 1 này trong câu truy vấn find bởi vị mongodb không hỗ trợ kiểu truy vấn mixed này
Chẳng hạn db.teacher.find({}, {"name":0, age:1})  => fail không hiển thị

2. Một số lệnh truy vấn riêng biệt

a. Các toán tử liên quan tới update
    Các phương thức update trong tài liệu mongodb:
  • db.collection.updateOne: Cập nhật 1 row duy nhất
  • db.collection.updateMany: Cập nhật nhiều row
  • db.collection.replaceOne
  • db.collection.update: Cập nhật thông thường, theo mặc định nó giống updateOne nhưng nó có thêm lựa chọn option multi: true để thực hiện update nhiều giống như updateMany
  Các lựa chọn trong update
  • $set: chỉ thay đổi giá trị truyền vào từ set, đặc điểm là nếu thuộc tính trong set tồn tại thì nó sẽ thay đổi giống như đã query, ngược lại nếu ko tồn tại thì nó sẽ tự động thêm như là 1 fied mới  (trong trường hợp này nó tương đương với $push)
               vd: db.teacher.update({name:'manh'},{$set:{age:35}});
  • $push: Thêm mới 1 field: 
    • vd: db.teacher.update({_id: ObjectId("58086fd1368d9a3cbbf44055")},{$push:{gender: 'male'})
  • $mulThay đổi giá trị bằng cách nhân giá trị chỉ định trong scope $mul với giá trị hiện tại (Chú ý: nếu field đặt trong scope $mul này không tồn tại => )
  • $inc: Tăng thêm giá trị cho 1 trường nếu là số dương, giảm đi nếu là số âm
          vd: db.teacher.update({name:'manh',{$inc:{age:5})   ==> Age lúc này là 40 do trước là 35
  •  $unset: Hủy bỏ 1 thuộc tính cụ thể được chỉ định trong 1 row
          vddb.teacher.update({name:'manh'},{$unset:{age:1})  => Sẽ hủy thuộc tính age trong row có name = "manh"
  • upsert:true: Update 1 thong tin, neu khong có thì tự thêm mới 1 thông tin mới đó vào bảng
     vd: db.teacher.update({name:'duc'},{name:'duc',address:'hoaiduc'},{upsert:true});  => Tim trong db neu co name= 'duc' thi update thong tin name:'duc',address:'hoaiduc', khong thi tu dong them moi thong tin 1 row voi cac field tuong ung {name:'duc',address:'hoaiduc'}
  • $rename: thay doi ten field thanh 1 field khac
  • $min: Cập nhật 1 trường nếu giá trị của trường đó là nhó hơn trường hiện tại
        Vd: mình có bảng score như sau: { _id: 1, highScore: 800, lowScore: 200 }
            Cập nhật với min: db.scores.update( { _id: 1 }, { $min: { lowScore: 200 } } )
            -> Kết quả ko đổi... do lowScore = 200 = giá trị hiện tại
                Đổi lại thành db.scores.update( { _id: 1 }, { $min: { lowScore: 199 } } ) 
            -> kết quả db bị thay đổi
                { _id: 1, highScore: 800, lowScore: 199 }
     Chú ý: Nếu field trong scope $min không có thì nó sẽ tự động thêm 1 trường mới vào trong row đó
  • $maxtương tự toán tử min, nhưng cập nhật với trường lớn hơn trường hiện tại
  • $multi: true => cho phép update nhiều row, ngược lại là false => chỉ được 1 row
  • $exists: nếu là true sẽ hiển thị tất cả các collection chứa field đó, miễn là field đó tồn tại trong collection kể cả giá trị của field đó = null.
  • $setOnInsert: đi kèm với khối lệnh upsert, trong tài liệu mongodb có nói nếu sử dụng upsert = true mà có 1 dữ liệu mới được thêm vào bảng thì $setOnInsert sẽ gán các trường và giá trị chỉ định tương ứng trong khổi $setOnInsert vào dữ liệu được thêm mới này. Ngược lại nếu dữ liệu ko được insert vào (tức là chỉ cập nhật) thì xem như $setOnInsert này không có tác dụng gì hết
Chú ý: Nếu bạn chỉ update thông thường mà không sử dụng các toán tử ở trên thì nó sẽ ghi đè lên toàn bộ collection của bạn
    - vd: mình có 1 collection student với thông tin:  {name:”NguyenManh”, address:”GiaLam”, phone: ”0123456789”}
  Thực hiện update thông thường: 
       db.update({name: “NguyenManh”}, {address: “GiaLam HaNoi”})  
       => collection sau update sẽ là { address: “GiaLam Ha Noi”} mà không còn field name và phone trong đó nữa… Vì vậy bạn hay lên kết hợp với các toán tử ở trên như $set để tránh dẫn đến sai lầm này.
b. Toán tử liên quan tới Delete
  • db.teacher.remove(): xóa toàn bộ dữ liệu trong bảng teacher ó truncate trên csdl khác
  • db.teacher.remove({name:'manh'})  <=> Remove tất cả các field có name = 'manh'
  • db.teacher.remove({name:'manh'}, {justOne:true}) <=> Remove row đầu tiên trong bảng khớp vơi name = 'manh'. (Nghĩa là nếu bạn có 3 trường cùng có name là manh thì nó cũng vẫn chỉ remove trường được tìm thấy đầu tiên mà thôi)
Trên đây là một số lệnh cơ bản khi làm việc với mongodb. Còn rất nhiều lệnh để bạn khám phá thêm nữa. Tuy nhiên trong phạm vi hạn hẹp của bài viết mình chưa thể đề cập thêm được về các truy vấn nâng cao khác. Có thể mình sẽ hẹn các bạn vào một bài viết khác cũng về chủ để các query trong mongodb này nhưng ở phạm vi nâng cao hơn. Nếu thấy hữu ích hãy để lại chia sẻ và comment để cùng góp ý cùng với mình nhé!
Previous
Next Post »