MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Cần tìm giá trị xuất hiện thường xuyên nhất của một trường trong một tổng thể

Vâng, bạn không thể chỉ "trang điểm". toán tử dưới dạng $mode không phải là toán tử tổng hợp và những thứ duy nhất bạn có thể sử dụng là những thứ thực sự tồn tại .

Vì vậy, để trả về giá trị danh mục trong khoảng thời gian được nhóm xuất hiện nhiều nhất, trước tiên cần phải nhóm trên mỗi giá trị đó và trả về số lần xuất hiện. Sau đó, bạn có thể sắp xếp các kết quả này theo số lượng đó và trả về giá trị danh mục đã ghi lại số lượng cao nhất trong khoảng thời gian đó:

    // Filter dates
    { "$match": { 
        "dt": { 
            "$gt": new Date("October 13, 2010 12:00:00"), 
            "$lt": new Date("November 13, 2010 12:00:00")
        } 
    }},

    // Group by hour and category, with avg and count
    { "$group": {
        "_id": {
            "dt": {
                "$add": [
                    {
                        "$subtract": [
                            { "$subtract": ["$dt", new Date(0)] },
                            {
                                "$mod": [
                                    { "$subtract": ["$dt", new Date(0)] },
                                    3600000//1000 * 60 * 60
                                ]
                            }
                        ]
                    },
                    new Date(0)
                ]
            },
            "category": "$category"
        }, 
        "price": { "$avg": "$price" },
        "count": { "$sum": 1 }
    }},
    // Sort on date and count
    { "$sort": { "_id.dt": 1, "count": -1 }},

    // Group on just the date, keeping the avg and the first category
    { "$group": {
        "_id": "$_id.dt",
        "price": { "$avg": "$price"}
        "category": { "$first": "$_id.category" }
    }}

Vì vậy, $group vào cả ngày và danh mục và giữ lại số lượng danh mục qua $sum . Sau đó, bạn $sort vì vậy "số lượng" lớn nhất ở trên cùng cho mỗi ngày được nhóm. Và cuối cùng sử dụng $first khi bạn áp dụng một $group khác chỉ được áp dụng cho chính ngày đó, để trả về danh mục đó với số lượng lớn nhất cho mỗi ngày.

Đừng để bị cám dỗ bởi các toán tử như $max vì họ không làm việc ở đây. Sự khác biệt chính là sự liên kết "gắn liền" với "bản ghi / tài liệu" được tạo cho mỗi giá trị danh mục. Vì vậy, nó không phải là "số lượng" tối đa bạn muốn hoặc giá trị "danh mục" tối đa, mà thay vào đó là giá trị danh mục "tạo ra" số lượng lớn nhất. Do đó có $sort cần thiết ở đây.

Cuối cùng, một số thói quen bạn "nên" phá bỏ:

  • Không sử dụng dữ liệu phiên bản ngày không định dạng UTC làm đầu vào trừ khi bạn thực sự biết mình đang làm gì. Ngày sẽ luôn được chuyển đổi sang UTC, vì vậy ít nhất trong danh sách thử nghiệm, bạn nên quen với việc chỉ định giá trị ngày theo cách đó.

  • Theo cách khác, nó có thể trông gọn gàng hơn một chút nhưng những thứ như 1000 * 60 * 60 là nhiều mã mô tả rõ ràng hơn về những gì nó đang làm so với 3600000 . Cùng một giá trị, nhưng một dạng biểu thị đơn vị thời gian trong nháy mắt.

  • Kết hợp _id khi chỉ có một giá trị duy nhất cũng có thể gây nhầm lẫn cho các vấn đề. Vì vậy, có rất ít điểm trong việc tích lũy _id.dt nếu đó là giá trị duy nhất hiện tại. Khi có nhiều thuộc tính trong _id sau đó nó là tốt. Nhưng các giá trị đơn lẻ chỉ nên được gán lại ngay cho _id một mình. Không có gì khác được, và độc thân là khá rõ ràng.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Bắt đầu MongoDB từ bên trong tác vụ Grunt

  2. Làm thế nào để hiển thị dữ liệu vô danh, tùy ý trong HTML với node.js / mongodb

  3. Cách cập nhật tài liệu MongoDB với mảng tài liệu con

  4. Mongodb 4:Không khởi động được mongod.service:Không tìm thấy đơn vị mongod.service

  5. 8 cách để bắt đầu một ngày trong MongoDB