Làm thế nào để bạn truy vấn cho không phải là null null trong Mongo?


Câu trả lời:


812

Điều này sẽ trả về tất cả các tài liệu có khóa gọi là "URL IMAGE", nhưng chúng vẫn có thể có giá trị null.

db.mycollection.find({"IMAGE URL":{$exists:true}});

Điều này sẽ trả về tất cả các tài liệu có cả khóa gọi là "URL IMAGE" giá trị khác không.

db.mycollection.find({"IMAGE URL":{$ne:null}});

Ngoài ra, theo các tài liệu, $ tồn tại hiện không thể sử dụng một chỉ mục, nhưng $ ne thì có thể.

Chỉnh sửa: Thêm một số ví dụ do quan tâm đến câu trả lời này

Đưa ra các chèn:

db.test.insert({"num":1, "check":"check value"});
db.test.insert({"num":2, "check":null});
db.test.insert({"num":3});

Điều này sẽ trả về cả ba tài liệu:

db.test.find();

Điều này sẽ chỉ trả lại tài liệu thứ nhất và thứ hai:

db.test.find({"check":{$exists:true}});

Điều này sẽ chỉ trả lại tài liệu đầu tiên:

db.test.find({"check":{$ne:null}});

Điều này sẽ chỉ trả lại tài liệu thứ hai và thứ ba:

db.test.find({"check":null})

13
Theo tài liệu, $ne bao gồm các tài liệu không chứa trường . Điều này đã thay đổi kể từ khi bạn đăng câu trả lời? docs.mongodb.org/manual/reference/operator/query/ne
Andrew Mao

2
Tôi không tin rằng điều đó đã thay đổi. Khi kiểm tra $ ne, giá trị được kiểm tra trong tất cả các tài liệu, bao gồm cả những tài liệu không chứa trường, nhưng $ ne: null vẫn không khớp với tài liệu không chứa trường do giá trị của trường vẫn là null, mặc dù trường không tồn tại trong tài liệu đó.
Tim Gautier

2
Làm thế nào để bạn chỉ phù hợp với tài liệu thứ hai?
BT

1
@River Tôi đã kiểm tra khi tôi viết bài này 3 năm trước và, để chắc chắn, tôi chỉ cần cài đặt Mongo và thử lại lần nữa. Nó vẫn hoạt động theo cùng một cách, câu trả lời là chính xác. Truy vấn thứ 2 đến cuối cùng chỉ trả về tài liệu thứ 1.
Tim Gautier

1
Các ví dụ đưa ra làm cho nó thực sự dễ hiểu làm thế nào để sử dụng này. :-)
Eric Dela Cruz

92

Một lớp lót là tốt nhất:

db.mycollection.find({ 'fieldname' : { $exists: true, $ne: null } });

Đây,

mycollection : đặt tên bộ sưu tập mong muốn của bạn

tên trường : đặt tên trường mong muốn của bạn

Giải thích:

$ tồn tại : Khi đúng, $ tồn tại khớp với các tài liệu có chứa trường, bao gồm các tài liệu có giá trị trường là null. Nếu là sai, truy vấn chỉ trả về các tài liệu không chứa trường.

$ ne chọn các tài liệu trong đó giá trị của trường không bằng giá trị được chỉ định. Điều này bao gồm các tài liệu không chứa trường.

Vì vậy, trong trường hợp được cung cấp của bạn, truy vấn sau sẽ trả về tất cả các tài liệu có trường imageurl tồn tại và không có giá trị null:

db.mycollection.find({ 'imageurl' : { $exists: true, $ne: null } });

11
$exists: truelà dư thừa, $ne: nulllà đủ.
Stanislav Karakhanov

Đây phải là câu trả lời tốt nhất. $exists: truetrả về nullgiá trị quá. Phải có cả hai $exists: true$ne: null. Nó KHÔNG dư thừa.
Ismail Kattakath

47

Trong pymongo bạn có thể sử dụng:

db.mycollection.find({"IMAGE URL":{"$ne":None}});

Bởi vì pymongo đại diện cho mongo "null" là python "Không".


18
db.collection_name.find({"filed_name":{$exists:true}});

tìm nạp các tài liệu có chứa tên_bạn này ngay cả khi nó là null.

Đề xuất của tôi:

db.collection_name.find({"field_name":{$type:2}}) //type:2 == String

Bạn có thể kiểm tra loại thuộc tính bắt buộc, nó sẽ trả về tất cả các tài liệu mà trường_name được truy vấn có chứa một giá trị vì bạn đang kiểm tra loại khác của tệp đã nộp nếu không có điều kiện loại không khớp nên sẽ không có gì được trả về.

Nb : nếu field_name có một chuỗi rỗng có nghĩa là "", nó sẽ được trả về. Đây là hành vi tương tự cho

db.collection_name.find({"filed_name":{$ne:null}});

Xác nhận thêm:

Được rồi, vì vậy chúng tôi chưa hoàn thành nhưng chúng tôi cần một điều kiện bổ sung.

db.collection_name.
find({ "field_name":{$type:2},$where:"this.field_name.length >0"})

HOẶC LÀ

db.collection_name.
find({ "field_name":{$ne:null},$where:"this.field_name.length >0"})

Tài liệu tham khảo


14

Chia sẻ cho độc giả tương lai.

Truy vấn này hoạt động với chúng tôi (truy vấn được thực hiện từ la bàn MongoDB ):

{
  "fieldName": {
    "$nin": [
      "",
      null
    ]
  }
}

1
{$ tồn tại: true, $ ne: null} không hiển thị kết quả chính xác. Truy vấn của bạn hoạt động tốt
Oleksandr Buchek

1
Hãy cẩn thận, $ nin thường không tối ưu hóa các chỉ số
Wheezil

4
db.<collectionName>.find({"IMAGE URL":{"$exists":"true"}, "IMAGE URL": {$ne: null}})

Đây có phải là một tài liệu Json hợp lệ? Hai thuộc tính có cùng tên trong tài liệu truy vấn. Không chắc chắn làm thế nào bạn sẽ xây dựng nó trong bộ nhớ nếu bạn phải.
BrentR

4

Trong trường hợp lý tưởng, bạn muốn kiểm tra cả ba giá trị , null , "" hoặc trống (trường không tồn tại trong bản ghi)

Bạn có thể làm như sau.

db.users.find({$and: [{"name" : {$nin: ["", null]}}, {"name" : {$exists: true}}]})

3

Một lựa chọn khác chưa được đề cập, nhưng đó có thể là một lựa chọn hiệu quả hơn đối với một số người (sẽ không hoạt động với các mục NULL) là sử dụng một chỉ mục thưa thớt (các mục trong chỉ mục chỉ tồn tại khi có gì đó trong trường). Đây là một tập dữ liệu mẫu:

db.foo.find()
{ "_id" : ObjectId("544540b31b5cf91c4893eb94"), "imageUrl" : "http://example.com/foo.jpg" }
{ "_id" : ObjectId("544540ba1b5cf91c4893eb95"), "imageUrl" : "http://example.com/bar.jpg" }
{ "_id" : ObjectId("544540c51b5cf91c4893eb96"), "imageUrl" : "http://example.com/foo.png" }
{ "_id" : ObjectId("544540c91b5cf91c4893eb97"), "imageUrl" : "http://example.com/bar.png" }
{ "_id" : ObjectId("544540ed1b5cf91c4893eb98"), "otherField" : 1 }
{ "_id" : ObjectId("544540f11b5cf91c4893eb99"), "otherField" : 2 }

Bây giờ, tạo chỉ mục thưa thớt trên trường imageUrl:

db.foo.ensureIndex( { "imageUrl": 1 }, { sparse: true } )
{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

Bây giờ, luôn có một cơ hội (và đặc biệt là với một tập dữ liệu nhỏ như mẫu của tôi) thay vì sử dụng một chỉ mục, MongoDB sẽ sử dụng quét bảng, ngay cả đối với truy vấn chỉ mục được bảo hiểm tiềm năng. Hóa ra nó cho tôi một cách dễ dàng để minh họa sự khác biệt ở đây:

db.foo.find({}, {_id : 0, imageUrl : 1})
{ "imageUrl" : "http://example.com/foo.jpg" }
{ "imageUrl" : "http://example.com/bar.jpg" }
{ "imageUrl" : "http://example.com/foo.png" }
{ "imageUrl" : "http://example.com/bar.png" }
{  }
{  }

OK, vì vậy các tài liệu bổ sung không imageUrlcó được trả lại, chỉ trống, không phải những gì chúng tôi muốn. Chỉ cần xác nhận lý do tại sao, hãy giải thích:

db.foo.find({}, {_id : 0, imageUrl : 1}).explain()
{
    "cursor" : "BasicCursor",
    "isMultiKey" : false,
    "n" : 6,
    "nscannedObjects" : 6,
    "nscanned" : 6,
    "nscannedObjectsAllPlans" : 6,
    "nscannedAllPlans" : 6,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 0,
    "server" : "localhost:31100",
    "filterSet" : false
}

Vì vậy, vâng, BasicCursorbằng với quét bảng, nó không sử dụng chỉ mục. Hãy buộc truy vấn sử dụng chỉ mục thưa thớt của chúng tôi bằng hint():

db.foo.find({}, {_id : 0, imageUrl : 1}).hint({imageUrl : 1})
{ "imageUrl" : "http://example.com/bar.jpg" }
{ "imageUrl" : "http://example.com/bar.png" }
{ "imageUrl" : "http://example.com/foo.jpg" }
{ "imageUrl" : "http://example.com/foo.png" }

Và có kết quả mà chúng tôi đang tìm kiếm - chỉ những tài liệu có trường được điền mới được trả về. Điều này cũng chỉ sử dụng chỉ mục (tức là nó là một truy vấn chỉ mục được bảo hiểm), vì vậy chỉ có chỉ mục cần có trong bộ nhớ để trả về kết quả.

Đây là trường hợp sử dụng chuyên biệt và thường không thể được sử dụng (xem các câu trả lời khác cho các tùy chọn đó). Cụ thể, cần lưu ý rằng vì mọi thứ bạn không thể sử dụng count()theo cách này (ví dụ của tôi, nó sẽ trả về 6 chứ không phải 4), vì vậy vui lòng chỉ sử dụng khi thích hợp.


Các trường văn bản luôn là các chỉ mục thưa thớt, bạn không cần phải xác định rõ ràng. chỉ 2 xu của tôi.
alianos-

3

Cách đơn giản nhất để kiểm tra sự tồn tại của cột trong la bàn mongo là:

{ 'column_name': { $exists: true } }

1
Vấn đề với điều này là nó giả định trường thực sự không bao giờ tồn tại, nhưng OP dường như chỉ ra (từ tiêu đề) rằng nó có thể tồn tại nhưng được đặt thành null rõ ràng.
Carighan

-10

Truy vấn sẽ là

db.mycollection.find({"IMAGE URL":{"$exists":"true"}})

nó sẽ trả về tất cả các tài liệu có "URL IMAGE" làm khóa ...........


1
@kilianc Điều đó không đúng. $ tồn tại cũng sẽ nắm bắt các giá trị null. Xem docs.mongodb.org/manual/reference/operator/query/exists
dorvak

@dorvak chính xác, đó là lý do tại sao điều đó sẽ không thỏa mãn trường hợp sử dụng trong câu hỏi.
kilianc

Câu trả lời này là sai vì $existskiểm tra khóa "IMAGE URL"và không xem đó là giá trị ( null) và sẽ trả lại tài liệu với "IMAGE URL" : null.
David Hariri
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.