जबकि मैं टिप्पणियों के साथ खड़ा हूं कि मुझे नहीं लगता कि जिस तरह से आप अपने प्रश्न को फिर से लिख रहे हैं, वास्तव में आपके पास एक विशिष्ट समस्या से संबंधित है, मैं किसी मोंगोडीबी प्रकार के समाधान में मुहावरेदार एसक्यूएल तरीके की व्याख्या करने के लिए किसी तरह जाऊंगा। मैं इस बात पर कायम हूं कि आपका वास्तविक समाधान अलग होगा लेकिन आपने हमें वह समस्या नहीं, बल्कि केवल SQL के साथ प्रस्तुत किया है।
तो स्पष्टता के लिए इस सूची में _id फ़ील्ड को हटाते हुए निम्नलिखित दस्तावेज़ों को एक नमूना सेट के रूप में मानें:
{ "name" : "a", "type" : "b" }
{ "name" : "a", "type" : "c" }
{ "name" : "b", "type" : "c" }
{ "name" : "b", "type" : "a" }
{ "name" : "a", "type" : "b" }
{ "name" : "b", "type" : "c" }
{ "name" : "f", "type" : "e" }
{ "name" : "z", "type" : "z" }
{ "name" : "z", "type" : "z" }
यदि हम उसी डेटा पर प्रस्तुत SQL को चलाते हैं तो हमें यह परिणाम प्राप्त होगा:
a|b
a|c
a|c
b|c
b|a
b|a
a|b
b|c
हम देख सकते हैं कि 2 दस्तावेज़ मेल नहीं खाते हैं, और फिर SQL ऑपरेशन के तर्क को पूरा करते हैं। तो इसे कहने का दूसरा तरीका यह है कि "कौन से दस्तावेज़ों को "नाम" की कुंजी दी जाती है करें एक . से अधिक हैं कुंजी "प्रकार" में संभावित मान।
यह देखते हुए कि, एक मोंगो दृष्टिकोण लेते हुए, हम उन वस्तुओं के लिए क्वेरी कर सकते हैं जो नहीं दी गई शर्त का मिलान करें। इतना प्रभावी ढंग से रिवर्स परिणाम का:
db.sample.aggregate([
// Store unique documents grouped by the "name"
{$group: {
_id: "$name",
comp: {
$addToSet: {
name:"$name",
type: "$type"
}
}
}},
// Unwind the "set" results
{$unwind: "$comp"},
// Push the results back to get the unique count
// *note* you could not have done this with alongside $addtoSet
{$group: {
_id: "$_id",
comp: {
$push: {
name: "$comp.name",
type: "$comp.type"
}
},
count: {$sum: 1}
}},
// Match only what was counted once
{$match: {count: 1}},
// Unwind the array
{$unwind: "$comp"},
// Clean up to "name" and "type" only
{$project: { _id: 0, name: "$comp.name", type: "$comp.type"}}
])
यह ऑपरेशन परिणाम देगा:
{ "name" : "f", "type" : "e" }
{ "name" : "z", "type" : "z" }
अब SQL क्वेरी के समान परिणाम प्राप्त करने के लिए हम उन परिणामों को लेंगे और उन्हें किसी अन्य क्वेरी में चैनल करेंगे:
db.sample.find({$nor: [{ name: "f", type: "e"},{ name: "z", type: "z"}] })
जो अंतिम मिलान परिणाम के रूप में आता है:
{ "name" : "a", "type" : "b" }
{ "name" : "a", "type" : "c" }
{ "name" : "b", "type" : "c" }
{ "name" : "b", "type" : "a" }
{ "name" : "a", "type" : "b" }
{ "name" : "b", "type" : "c" }
तो यह काम करेगा, हालांकि एक चीज जो इसे अव्यावहारिक बना सकती है वह है जहां दस्तावेजों की संख्या तुलना की जा रही है बहुत बड़ा है, हमने उन परिणामों को एक सरणी में संकुचित करने की कार्य सीमा को पार कर लिया है।
इसे नकारात्मक . के उपयोग से भी थोड़ा नुकसान होता है अंतिम खोज ऑपरेशन में जो संग्रह के स्कैन को बाध्य करेगा। लेकिन सभी निष्पक्षता में SQL क्वेरी के बारे में भी यही कहा जा सकता है जो समान नकारात्मक . का उपयोग करती है आधार।
संपादित करें
निश्चित रूप से मैंने जो उल्लेख नहीं किया वह यह है कि यदि परिणाम सेट दूसरी तरफ जाता है और आप अधिक से मेल खाते हैं कुल से बहिष्कृत वस्तुओं में परिणाम, फिर अपनी इच्छित कुंजी प्राप्त करने के लिए तर्क को उलट दें। बस $match को इस प्रकार बदलें:
{$match: {$gt: 1}}
और वह परिणाम होगा, शायद वास्तविक दस्तावेज नहीं लेकिन यह एक परिणाम है। इसलिए आपको नकारात्मक मामलों से मेल खाने के लिए किसी अन्य क्वेरी की आवश्यकता नहीं है।
और, अंततः यह मेरी गलती थी क्योंकि मैं मुहावरेदार अनुवाद पर इतना केंद्रित था कि मैंने पढ़ा नहीं किया आपके प्रश्न की अंतिम पंक्ति, जहां करें कहें कि आप एक . ढूंढ रहे थे दस्तावेज़।
बेशक, वर्तमान में अगर वह परिणाम आकार 16 एमबी से बड़ा है तो आप फंस गए हैं। कम से कम 2.6 . तक रिलीज, जहां एकत्रीकरण संचालन के परिणाम एक कर्सर
, ताकि आप इसे .find()
. की तरह पुनरावृति कर सकें ।
2.6 . में भी पेश किया गया $size
है कोड>
ऑपरेटर जिसका उपयोग दस्तावेज़ में एक सरणी के आकार को खोजने के लिए किया जाता है। तो यह दूसरे $अनविंड
. को हटाने में मदद करेगा और $समूह
जिनका उपयोग सेट की लंबाई प्राप्त करने के लिए किया जाता है। यह क्वेरी को तेज़ रूप में बदल देता है:
db.sample.aggregate([
{$group: {
_id: "$name",
comp: {
$addToSet: {
name:"$name",
type: "$type"
}
}
}},
{$project: {
comp: 1,
count: {$size: "$comp"}
}},
{$match: {count: {$gt: 1}}},
{$unwind: "$comp"},
{$project: { _id: 0, name: "$comp.name", type: "$comp.type"}}
])
और MongoDB 2.6.0-rc0 वर्तमान में उपलब्ध है यदि आप इसे केवल व्यक्तिगत उपयोग, या विकास/परीक्षण के लिए कर रहे हैं।
कहानी की शिक्षा। हां आप कर सकते हैं करो, लेकिन क्या आप सच में चाहते हैं या जरूरत ऐसा करने के लिए? तो शायद नहीं, और यदि आपने विशिष्ट व्यावसायिक मामले के बारे में एक अलग प्रश्न पूछा है, तो आपको एक अलग उत्तर मिल सकता है। लेकिन फिर यह आप जो चाहते हैं उसके लिए बिल्कुल सही हो सकता है।
नोट
यह उल्लेख करने योग्य है कि जब आप SQL के परिणामों को देखते हैं, तो यह त्रुटिपूर्ण रूप से डुप्लिकेट होगा यदि आपने DISTINCT
. का उपयोग नहीं किया तो अन्य उपलब्ध प्रकार विकल्पों के कारण कई आइटम उन मूल्यों या अनिवार्य रूप से किसी अन्य समूह के लिए। लेकिन यही वह परिणाम है जो इस प्रक्रिया द्वारा MongoDB का उपयोग करके तैयार किया जा रहा था।
सिकंदर के लिए
यह वर्तमान 2.4.x संस्करणों से शेल में कुल का आउटपुट है:
{
"result" : [
{
"name" : "f",
"type" : "e"
},
{
"name" : "z",
"type" : "z"
}
],
"ok" : 1
}
तो ऐसा करने के लिए एक var को पास करने के लिए $ और न ही दूसरी खोज में शर्त के रूप में, इस तरह:
var cond = db.sample.aggregate([ .....
db.sample.find({$nor: cond.result })
और आपको वही परिणाम मिलना चाहिए। नहीं तो अपने ड्राइवर से सलाह लें।