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

Tối ưu hóa truy vấn MongoDB

Những gì bạn muốn là một kết quả "tìm kiếm theo từng khía cạnh" nơi bạn nắm giữ số liệu thống kê về các cụm từ phù hợp trong tập hợp kết quả hiện tại. Sau đó, mặc dù có những sản phẩm "dường như" thực hiện tất cả công việc trong một phản hồi duy nhất, bạn phải xem xét rằng hầu hết các công cụ lưu trữ chung sẽ cần nhiều hoạt động.

Với MongoDB, bạn có thể sử dụng hai truy vấn để nhận kết quả và một truy vấn khác để lấy thông tin khía cạnh. Điều này sẽ cung cấp các kết quả tương tự với các kết quả theo từng khía cạnh có sẵn từ các sản phẩm công cụ tìm kiếm chuyên dụng như Solr hoặc ElasticSearch.

Nhưng để làm điều này một cách hiệu quả, bạn muốn đưa nó vào tài liệu của mình theo cách nó có thể được sử dụng một cách hiệu quả. Một biểu mẫu rất hiệu quả cho những gì bạn muốn là sử dụng một mảng dữ liệu được mã hóa:

 {
     "otherData": "something",
     "facets": [
         "country:UK",
         "city:London-UK",
         "genre:Student"
     ]
 }

Vì vậy, "tập dữ liệu" là một trường duy nhất trong tài liệu của bạn và không ở nhiều vị trí. Điều này làm cho nó rất dễ dàng lập chỉ mục và truy vấn. Sau đó, bạn có thể tổng hợp hiệu quả các kết quả của mình và nhận tổng số cho từng khía cạnh:

User.aggregate(
    [
        { "$unwind": "$facets" },
        { "$group": {
            "_id": "$facets",
            "count": { "$sum": 1 }
        }}
    ],
    function(err,results) {

    }
);

Hoặc lý tưởng hơn với một số tiêu chí trong $match :

User.aggregate(
    [
        { "$match": { "facets": { "$in": ["genre:student"] } } },
        { "$unwind": "$facets" },
        { "$group": {
            "_id": "$facets",
            "count": { "$sum": 1 }
        }}
    ],
    function(err,results) {

    }
);

Cuối cùng đưa ra một phản hồi như:

{ "_id": "country:FR", "count": 50 },
{ "_id": "country:UK", "count": 300 },
{ "_id": "city:London-UK", "count": 150 },
{ "_id": "genre:Student": "count": 500 }

Cấu trúc như vậy rất dễ xem qua và kiểm tra những thứ như "quốc gia" và "thành phố" rời rạc thuộc về một "quốc gia" vì dữ liệu đó chỉ được phân tách nhất quán bằng dấu gạch ngang "-".

Cố gắng trộn các tài liệu trong các mảng là một ý tưởng tồi. Cũng có giới hạn kích thước BSON là 16MB, do đó việc kết hợp các kết quả lại với nhau (đặc biệt nếu bạn đang cố gắng lưu giữ nội dung tài liệu) chắc chắn sẽ bị vượt quá trong phản hồi.

Đối với một cái gì đó đơn giản như sau đó nhận "tổng số" kết quả từ một truy vấn như vậy, sau đó chỉ cần tổng hợp các phần tử của một loại khía cạnh cụ thể. Hoặc chỉ đưa ra các đối số truy vấn giống nhau của bạn cho một .count() hoạt động:

User.count({ "facets": { "$in": ["genre:Student"] } },function(err,count) {

});

Như đã nói ở đây, đặc biệt là khi triển khai "phân trang" kết quả, thì vai trò nhận "Số lượng kết quả", "Số lượng khía cạnh" và "Trang kết quả" thực tế đều được ủy quyền cho các truy vấn "riêng biệt" đối với máy chủ.

Không có gì sai khi gửi song song từng truy vấn đó đến máy chủ và sau đó kết hợp một cấu trúc để cung cấp cho mẫu hoặc ứng dụng của bạn trông giống như kết quả tìm kiếm theo từng khía cạnh từ một trong những sản phẩm của công cụ tìm kiếm cung cấp loại phản hồi này.

Kết luận

Vì vậy, hãy đặt một cái gì đó vào tài liệu của bạn để đánh dấu các khía cạnh ở một nơi duy nhất. Một mảng các chuỗi được mã hóa hoạt động tốt cho mục đích này. Nó cũng hoạt động tốt với các biểu mẫu truy vấn như $in $all cho các điều kiện "hoặc" hoặc "và" trên các kết hợp lựa chọn khía cạnh.

Đừng thử và kết hợp các kết quả hoặc bổ sung lồng ghép chỉ để phù hợp với một số cấu trúc phân cấp đã nhận thấy, mà hãy duyệt qua các kết quả nhận được và sử dụng các mẫu đơn giản trong các mã thông báo. Nó rất đơn giản để

Chạy các truy vấn phân trang cho nội dung dưới dạng các truy vấn riêng biệt cho các khía cạnh hoặc tổng thể. Cố gắng đẩy tất cả nội dung trong các mảng và sau đó giới hạn chỉ để nhận được số lượng là không có ý nghĩa. Điều tương tự cũng sẽ áp dụng cho giải pháp RDBMS để làm điều tương tự, trong đó kết quả phân trang và trang hiện tại là các hoạt động truy vấn riêng biệt.

Có thêm thông tin được viết trên Blog MongoDB về Tìm kiếm theo khía cạnh với MongoDB cũng giải thích một số tùy chọn khác. Ngoài ra còn có các bài viết về tích hợp với các giải pháp tìm kiếm bên ngoài bằng cách sử dụng mongoconnector hoặc các cách tiếp cận khác.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Làm cách nào để thiết lập MongoDB trên máy chủ Node.js bằng node-mongodb-native trong môi trường EC2?

  2. Truy vấn Mongodb tháng cụ thể | năm không phải ngày

  3. Cập nhật trong forEach trên mongodb shell

  4. MongoDB trích xuất các giá trị từ BasicDBObject (Java)

  5. Tắt đúng cách kết nối cơ sở dữ liệu MongoDB từ trình điều khiển C # 2.1?