คุณค้นหาคำว่า“ ไม่เป็นโมฆะ” ใน Mongo ได้อย่างไร


410

ฉันต้องการที่จะดำเนินการค้นหาต่อไปนี้:

db.mycollection.find(HAS IMAGE URL)

สิ่งที่ควรเป็นไวยากรณ์ที่ถูกต้อง?


74
คำตอบสั้น ๆ : การ{ field : {$ne : null} }ตรวจสอบแบบสอบถามไม่ใช่docs.mongodb.org/manual/reference/operator/query/ne
Jaider

คำตอบ:


812

การดำเนินการนี้จะส่งคืนเอกสารทั้งหมดด้วยรหัสที่เรียกว่า "IMAGE URL" แต่พวกเขายังอาจมีค่า Null

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

การดำเนินการนี้จะส่งคืนเอกสารทั้งหมดพร้อมทั้งรหัสที่เรียกว่า "IMAGE URL" และค่าที่ไม่ใช่ค่า Null

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

นอกจากนี้ตามเอกสารมีอยู่ $ ปัจจุบันไม่สามารถใช้ดัชนี แต่ $ ne สามารถ

แก้ไข: การเพิ่มตัวอย่างเนื่องจากความสนใจในคำตอบนี้

รับเม็ดมีดเหล่านี้:

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

สิ่งนี้จะส่งคืนเอกสารทั้งสาม:

db.test.find();

นี่จะส่งคืนเอกสารแรกและเอกสารที่สองเท่านั้น:

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

นี่จะส่งคืนเอกสารแรกเท่านั้น:

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

นี่จะส่งคืนเอกสารที่สองและสามเท่านั้น:

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

12
ตามเอกสารรวมถึงเอกสารที่ไม่ประกอบด้วยสนาม$ne สิ่งนี้มีการเปลี่ยนแปลงตั้งแต่คุณโพสต์คำตอบหรือไม่ docs.mongodb.org/manual/reference/operator/query/ne
Andrew Mao

2
ฉันไม่เชื่อว่ามีการเปลี่ยนแปลง เมื่อตรวจสอบ $ ne ค่าจะถูกตรวจสอบในเอกสารทั้งหมดรวมถึงที่ไม่มีเขตข้อมูล แต่ $ ne: null จะยังคงไม่ตรงกับเอกสารที่ไม่มีเขตข้อมูลเนื่องจากค่าของเขตข้อมูลยังคงเป็นค่าว่าง แม้ว่าเขตข้อมูลจะไม่มีอยู่ในเอกสารนั้น
Tim Gautier

2
คุณจะจับคู่เอกสารที่สองอย่างไร
BT

1
@River ฉันตรวจสอบเมื่อฉันเขียนเมื่อ 3 ปีที่แล้วและเพื่อให้แน่ใจว่าฉันเพิ่งติดตั้ง Mongo และลองอีกครั้ง มันยังคงทำงานเหมือนเดิมคำตอบนั้นถูกต้อง แบบสอบถามที่ 2 ถึงสุดท้ายส่งคืนเฉพาะเอกสารที่ 1
Tim Gautier

1
ตัวอย่างที่ให้มาทำให้เข้าใจวิธีการใช้ :-)
Eric Dela Cruz

92

ซับหนึ่งที่ดีที่สุด:

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

ที่นี่

mycollection : วางชื่อคอลเลกชันที่คุณต้องการ

fieldname : วางชื่อฟิลด์ที่คุณต้องการ

คำอธิบาย:

$ มีอยู่ : เมื่อเป็นจริง $ จะตรงกับเอกสารที่มีฟิลด์รวมถึงเอกสารที่ค่าฟิลด์เป็นโมฆะ ถ้าเป็นเท็จแบบสอบถามจะส่งคืนเฉพาะเอกสารที่ไม่มีเขตข้อมูล

$ neเลือกเอกสารที่ค่าของฟิลด์ไม่เท่ากับค่าที่ระบุ รวมถึงเอกสารที่ไม่มีฟิลด์

ดังนั้นในกรณีที่คุณให้แบบสอบถามต่อไปนี้จะส่งคืนเอกสารทั้งหมดที่มีช่อง imageurl มีอยู่และไม่มีค่า null:

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

11
$exists: trueมี$ne: nullมากเกินพอ
Stanislav Karakhanov

นี่ควรเป็นคำตอบที่ดีที่สุด $exists: trueส่งคืนnullค่าเช่นกัน จะต้องมีทั้งมีและ$exists: true $ne: nullมันไม่ซ้ำซ้อน
Ismail Kattakath

47

ใน pymongo คุณสามารถใช้:

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

เนื่องจาก pymongo แทน mongo "null" เป็น python "None"


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

ดึงเอกสารที่มี filed_name นี้แม้ว่าจะเป็นโมฆะ

ข้อเสนอของฉัน:

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

คุณสามารถตรวจสอบประเภทของแอททริบิวต์ที่ต้องการมันจะส่งคืนเอกสารทั้งหมดที่ field_name สอบถามมีค่าเนื่องจากคุณกำลังตรวจสอบประเภทของไฟล์อื่นหากเป็นโมฆะเงื่อนไขประเภทไม่ตรงกันดังนั้นจะไม่มีการส่งคืนใด ๆ

Nb : ถ้า field_name มีสตริงว่างซึ่งหมายถึง "" มันจะถูกส่งคืนมันเป็นพฤติกรรมแบบเดียวกันสำหรับ

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

การตรวจสอบพิเศษ:

โอเคเรายังไม่เสร็จ แต่เราต้องการเงื่อนไขพิเศษ

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

หรือ

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

การอ้างอิง


14

การแบ่งปันสำหรับผู้อ่านในอนาคต

แบบสอบถามนี้ทำงานสำหรับเรา (แบบสอบถามดำเนินการจากเข็มทิศ MongoDB ):

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

1
{$ มีอยู่: จริง, $ ne: null} ไม่แสดงผลลัพธ์ที่ถูกต้อง ข้อความค้นหาของคุณใช้งานได้ดี
Oleksandr Buchek

1
ระวัง $ nin มักจะไม่ปรับให้เหมาะสมกับดัชนี
Wheezil

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

นี่เป็นเอกสาร Json ที่ถูกต้องหรือไม่ สองคุณสมบัติที่มีชื่อเดียวกันในเอกสารแบบสอบถาม ไม่แน่ใจว่าคุณจะสร้างมันอย่างไรในหน่วยความจำถ้าคุณต้อง
BrentR

4

ในกรณีที่เหมาะคุณต้องการที่จะทดสอบสำหรับทั้งสามค่า , null , ""หรือที่ว่างเปล่า (เขตไม่อยู่ในบันทึก)

คุณสามารถทำสิ่งต่อไปนี้

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

3

ทางเลือกที่ไม่ได้กล่าวถึง แต่อาจเป็นตัวเลือกที่มีประสิทธิภาพมากขึ้นสำหรับบางคน (จะไม่ทำงานกับ NULL รายการ) คือการใช้ดัชนีกระจัดกระจาย (รายการในดัชนีมีอยู่เฉพาะเมื่อมีบางสิ่งในเขตข้อมูล) นี่คือชุดข้อมูลตัวอย่าง:

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 }

ตอนนี้สร้างดัชนีกระจัดกระจายในฟิลด์ imageUrl:

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

ตอนนี้มีโอกาสเสมอ (และโดยเฉพาะอย่างยิ่งกับชุดข้อมูลขนาดเล็กเช่นตัวอย่างของฉัน) ที่แทนที่จะใช้ดัชนี MongoDB จะใช้การสแกนตารางแม้กระทั่งสำหรับแบบสอบถามดัชนีที่มีศักยภาพ มันกลับกลายเป็นว่าเป็นวิธีที่ง่ายในการอธิบายความแตกต่างที่นี่:

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" }
{  }
{  }

ตกลงดังนั้นเอกสารพิเศษที่ไม่มีimageUrlการส่งคืนจะว่างเปล่าไม่ใช่สิ่งที่เราต้องการ เพียงเพื่อยืนยันว่าทำไมให้อธิบาย:

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
}

ดังนั้นใช่BasicCursorเท่ากับการสแกนตารางมันไม่ได้ใช้ดัชนี ลองบังคับให้ข้อความค้นหาใช้ดัชนีเบาบางของเรากับ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" }

และมีผลลัพธ์ที่เรากำลังค้นหา - เฉพาะเอกสารที่มีเขตข้อมูลที่ส่งคืนเท่านั้น นอกจากนี้ยังใช้ดัชนีเท่านั้น (นั่นคือแบบสอบถามแบบครอบคลุม) ดังนั้นเฉพาะดัชนีที่ต้องอยู่ในหน่วยความจำเพื่อส่งคืนผลลัพธ์

นี่เป็นกรณีการใช้งานเฉพาะและไม่สามารถใช้งานได้โดยทั่วไป (ดูคำตอบอื่น ๆ สำหรับตัวเลือกเหล่านั้น) โดยเฉพาะอย่างยิ่งควรสังเกตว่าเป็นสิ่งที่ยืนคุณไม่สามารถใช้count()ด้วยวิธีนี้ (สำหรับตัวอย่างของฉันมันจะกลับ 6 ไม่ใช่ 4) ดังนั้นโปรดใช้เฉพาะเมื่อเหมาะสม


ช่องข้อความมักจะเป็นดัชนีกระจัดกระจายคุณไม่จำเป็นต้องระบุอย่างชัดเจน แค่ 2 เซ็นต์ของฉัน
alianos-

3

วิธีที่ง่ายที่สุดในการตรวจสอบการมีอยู่ของคอลัมน์ในเข็มทิศ mongo คือ:

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

1
ปัญหาเกี่ยวกับสิ่งนี้คือมันถือว่าสนามเป็นจริงไม่เคยยืนยัน แต่ OP ดูเหมือนว่าจะระบุ (จากพาดหัว) ว่ามันอาจมีอยู่ แต่จะถูกตั้งค่าเป็นโมฆะอย่างชัดเจน
Carighan

-10

แบบสอบถามจะเป็น

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

มันจะส่งคืนเอกสารทั้งหมดที่มี "IMAGE URL" เป็นกุญแจ ...........


1
@ kilianc นั่นไม่เป็นความจริง $ ที่มีอยู่จะจับค่า Null เช่นกัน ดูdocs.mongodb.org/manual/reference/operator/query/exists
dorvak

@dorvak แน่นอนนั่นคือเหตุผลที่จะไม่ตอบสนองกรณีใช้งานในคำถาม
kilianc

คำตอบนี้เป็นความผิดเพราะ$existsการตรวจสอบที่สำคัญ"IMAGE URL"และไม่ได้คิดว่ามันเป็นค่า ( null) และจะ"IMAGE URL" : nullกลับมาเอกสารที่มี
David Hariri
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.