2012-01-14 30 views
11

Tôi có một bộ sưu tập với một subdocument thẻ như:Làm thế nào để chọn các tài liệu phụ với MongoDB

Collection News : 
    title (string) 
    tags: [tag1, tag2...] 

Tôi muốn chọn tất cả các thẻ người bắt đầu với một mô hình, nhưng chỉ trả lại thẻ phù hợp.

tôi đã sử dụng một regex nhưng nó sẽ trả về tất cả các tin tức có chứa các từ khóa phù hợp, đây là truy vấn:

db.news.find({"tags":/^proga/i}, ["tags"]).sort({"tags":1}). 
    limit(0).skip(0) 

Câu hỏi của tôi là: Làm thế nào tôi có thể lấy lại tất cả các thẻ (chỉ), người phù hợp với mô hình ? (Mục đích cuối cùng là để làm cho một lĩnh vực autocomplete)

Tôi cũng đã cố gắng sử dụng riêng biệt, nhưng tôi đã không tìm thấy một cách để làm cho một riêng biệt với một tìm kiếm, nó luôn luôn trở về với tôi tất cả các thẻ :(

Cảm ơn thời gian của bạn

Trả lời

10

Tài liệu được nhúng không sưu tập Nhìn vào truy vấn của bạn:.. db tin tức .find sẽ trả lại tài liệu từ bộ sưu tập newstags không phải là một bộ sưu tập, và không thể được lọc

.. Ở đó tôi s một yêu cầu tính năng cho "tính năng thu thập ảo" này (SERVER-142), nhưng không mong đợi để xem điều này quá sớm, bởi vì nó "kế hoạch nhưng không được lên kế hoạch".

Bạn có thể thực hiện lọc phía máy khách hoặc di chuyển thẻ đến một bộ sưu tập riêng biệt. Bởi retrieving only a subset of fields - chỉ có trường tags - điều này sẽ nhanh chóng hợp lý.

Gợi ý: Regex của bạn sử dụng cờ /i, khiến không thể sử dụng chỉ mục. Chuỗi db của bạn phải được chuẩn hóa theo trường hợp (ví dụ: tất cả chữ thường)

+0

Cảm ơn câu trả lời, tôi sẽ cố gắng tạo một bộ sưu tập "thẻ" phù thủy có thể chứa tất cả các thẻ của tôi và làm bộ lọc trên thẻ này (nhưng không chắc chắn nó theo cách NOSQL) – Mush

13

Một chút muộn cho bữa tiệc, nhưng hy vọng sẽ giúp những người khác đang tìm kiếm giải pháp. Tôi đã tìm thấy một cách để làm điều này bằng cách sử dụng khung tổng hợp và kết hợp $ project và $ relax với $ match, bằng cách kết nối chúng lại với nhau. Tôi đã thực hiện nó sử dụng PHP nhưng bạn sẽ nhận được các ý chính:

$ops = array(
     array('$match' => array(
       'collectionColumn' => 'value', 
      ) 
     ), 
     array('$project' => array(
       'collection.subcollection' => 1 
      ) 
     ), 
     array('$unwind' => '$subCollection'), 
     array('$match' => array(
       subCollection.subColumn => 'subColumnValue' 
      ) 
     ) 
    ); 

Trận đấu đầu tiên và dự án được chỉ cần sử dụng để lọc ra để làm cho nó nhanh hơn, thì Thư giãn trên subcollection spits ra từng hạng mục subcollection bởi mục mà sau đó có thể được lọc bằng cách sử dụng kết quả cuối cùng.

Hy vọng điều đó sẽ hữu ích.

UPDATE (từ Ryan Wheale):

Bạn có thể sau đó $group dữ liệu trở lại vào cấu trúc ban đầu của nó. Nó giống như có một $elemMatch trả về nhiều hơn một subdocument:

array('$group' => array(
     '_id' => '$_id', 
     'subcollection' => array(
      '$push' => '$subcollection' 
     ) 
    ) 
); 

tôi dịch này từ Node để PHP, vì vậy tôi đã không kiểm tra trong PHP. Nếu ai muốn phiên bản Node, hãy để lại bình luận dưới đây và tôi sẽ bắt buộc.

+1

Dude, thiên tài thuần khiết.Tôi không thể mô tả bóng đèn phát ra khi tôi tìm thấy nó. Bạn cũng có thể '$ group' các mục trở lại với nhau thành cấu trúc ban đầu của chúng. Tôi đã cần tương đương với '$ elemMatch' chiếu mà sẽ trở lại nhiều hơn kết quả đầu tiên. Cảm ơn!! –

Các vấn đề liên quan