2012-09-10 33 views
16

Tôi đang cố tạo một dịch vụ web bằng MongoDB và Flask (sử dụng trình điều khiển pymongo). Một truy vấn đến cơ sở dữ liệu trả về tài liệu với trường "_id" được bao gồm, tất nhiên. Tôi không muốn gửi nó cho khách hàng, vậy làm cách nào để xóa nó?Xóa phần tử _id khỏi các kết quả Pymongo

Dưới đây là một con đường Flask:

@app.route('/theobjects') 
def index(): 
    objects = db.collection.find() 
    return str(json.dumps({'results': list(objects)}, 
     default = json_util.default, 
     indent = 4)) 

này trả về:

{ 
"results": [ 
    { 
     "whatever": { 
      "field1": "value", 
      "field2": "value", 
     }, 
     "whatever2": { 
      "field3": "value" 
     }, 
     ... 
     "_id": { 
      "$oid": "..." 
     }, 

    ... 
    } 
]} 

tôi nghĩ rằng nó là một cuốn từ điển và tôi chỉ có thể xóa các phần tử trước khi trở về nó:

del objects['_id'] 

Nhưng điều đó trả về TypeError:

TypeError: 'Cursor' object does not support item deletion 

Vì vậy, nó không phải là một từ điển, nhưng một cái gì đó tôi phải lặp lại với mỗi kết quả như một từ điển. Vì vậy, tôi cố gắng thực hiện điều đó bằng mã này:

for object in objects: 
    del object['_id'] 

Từ điển đối tượng giống như cách tôi muốn, nhưng con trỏ đối tượng trống. Vì vậy, tôi cố gắng tạo ra một từ điển mới và sau khi xóa _id từ mỗi, thêm vào một từ điển mới mà Flask sẽ trở lại:

new_object = {} 
for object in objects: 
    for key, item in objects.items(): 
     if key == '_id': 
      del object['_id'] 
      new_object.update(object) 

này chỉ trả về một cuốn từ điển với các phím đầu tiên cấp và không có gì khác.

Vì vậy, đây là loại vấn đề điển hình lồng nhau chuẩn, nhưng tôi cũng bị sốc rằng MongoDB không có cách nào để dễ dàng giải quyết vấn đề này.

Các MongoDB documentation giải thích rằng bạn có thể loại trừ _id với

{ _id : 0 } 

Nhưng điều đó không làm gì với pymongo. Pymongo documentation giải thích rằng bạn có thể liệt kê các trường bạn muốn trả về, nhưng "(" _id "sẽ luôn được đưa vào)". Nghiêm túc? Không có cách nào xung quanh điều này? Có cái gì đơn giản và ngu ngốc mà tôi nhìn thấy ở đây không?

+0

Xác nhận quyền sở hữu thực sự của bạn ở đây là gì? Mã của bạn để tạo ra một dict mới là lạ và không cần thiết. Vấn đề thực sự của bạn là gì? –

+0

Vấn đề của tôi là .find ({}, {'_id': False}) không loại trừ _id. Tuy nhiên nó là một vấn đề với mã của tôi và nó bây giờ làm việc. Cảm ơn bạn đã giúp đỡ. – ddw

+0

"nhưng con trỏ đối tượng trống": đó là vì bạn chỉ có thể lặp lại một lần, vì vậy bạn cần lặp lại, nhận lệnh tiếp theo, xóa '_id', đặt dict vào danh sách và cuối danh sách đó, không các đối tượng. –

Trả lời

53

Để loại trừ lĩnh vực _id trong một truy vấn tìm trong pymongo, bạn có thể sử dụng:

db.collection.find({}, {'_id': False}) 

Các tài liệu có phần gây hiểu nhầm về điều này vì nó nói rằng trường _id luôn được bao gồm.Nhưng bạn có thể loại trừ nó như được hiển thị ở trên.

+0

Cảm ơn, điều này là chính xác. Tôi đã cố gắng này trước khi gửi bài nhưng tôi đoán có một vấn đề với chuỗi tôi đã đi qua trong tham số đầu tiên. Tôi đã sửa nó và bây giờ tất cả đều tốt. – ddw

2

Bạn đang kêu gọi

del objects['_id'] 

trên đối tượng con trỏ!

Đối tượng con trỏ rõ ràng là có thể lặp lại trong tập hợp kết quả và không phải là tài liệu đơn lẻ mà bạn có thể thao tác.

for obj in objects: 
    del obj['_id'] 

có thể là những gì bạn muốn.

Vì vậy, yêu cầu của bạn là hoàn toàn sai như mã sau đây cho thấy:

import pymongo 

c = pymongo.Connection() 
db = c['mydb'] 
db.foo.remove({}) 
db.foo.save({'foo' : 42}) 

for row in db.foo.find(): 
    del row['_id'] 
    print row 



$ bin/python foo.py 

> {u'foo': 42} 
+0

Vâng, tôi cũng đã thử mã của bạn trước khi đăng bài ban đầu. Nhưng sau đó tôi sẽ kết hợp các từ điển lồng nhau này vào một từ điển có thể được chuyển cho khách hàng như thế nào? Ngoài ra, tôi nhận ra rằng tôi đã cố gắng xóa một đối tượng con trỏ, đó là lý do tại sao tôi nói "Vì vậy, nó không phải là một từ điển, nhưng một cái gì đó tôi phải lặp lại với mỗi kết quả như một từ điển." Có lẽ tôi nên bỏ qua quá trình khám phá của mình nhưng tôi nghĩ càng có nhiều thông tin càng tốt. – ddw

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