MongoDB
 sql >> डेटाबेस >  >> NoSQL >> MongoDB

मोंगोडब में एकाधिक सीमा की स्थिति

आम तौर पर आप जो वर्णन कर रहे हैं वह मोंगोडीबी समुदाय के आसपास एक अपेक्षाकृत सामान्य प्रश्न है जिसे हम "शीर्ष n के रूप में वर्णित कर सकते हैं। परिणाम समस्या"। यह तब होता है जब कुछ इनपुट दिया जाता है जिसे किसी तरह से सॉर्ट किया जाता है, शीर्ष n कैसे प्राप्त करें डेटा में मनमाने इंडेक्स मानों पर भरोसा किए बिना परिणाम।

MongoDB के पास $first है ऑपरेटर जो एकत्रीकरण ढांचे के लिए उपलब्ध है जो समस्या के "शीर्ष 1" भाग से संबंधित है, क्योंकि यह वास्तव में समूह सीमा पर पाया गया "पहला" आइटम लेता है, जैसे आपका "प्रकार"। लेकिन निश्चित रूप से "एक" से अधिक परिणाम प्राप्त करना थोड़ा अधिक शामिल हो जाता है। n . से निपटने के लिए अन्य ऑपरेटरों को संशोधित करने के बारे में इस पर कुछ JIRA मुद्दे हैं परिणाम या "प्रतिबंधित" या "टुकड़ा"। विशेष रूप से SERVER-6074 . लेकिन समस्या को कुछ तरीकों से नियंत्रित किया जा सकता है।

MongoDB संग्रहण के लिए रेल सक्रिय रिकॉर्ड पैटर्न के लोकप्रिय कार्यान्वयन हैं Mongoid और मोंगो मैपर , दोनों एक .collection के माध्यम से "मूल" mongodb संग्रह कार्यों तक पहुंच की अनुमति देते हैं एक्सेसर। मूल रूप से आपको मूल विधियों जैसे .एग्रीगेट () जो सामान्य सक्रिय रिकॉर्ड एकत्रीकरण की तुलना में अधिक कार्यक्षमता का समर्थन करता है।

यहाँ मोंगोइड के साथ एक एकत्रीकरण दृष्टिकोण है, हालाँकि एक बार जब आप मूल संग्रह वस्तु तक पहुँच प्राप्त कर लेते हैं तो सामान्य कोड नहीं बदलता है:

require "mongoid"
require "pp";

Mongoid.configure.connect_to("test");

class Item
  include Mongoid::Document
  store_in collection: "item"

  field :type, type: String
  field :pos, type: String
end

Item.collection.drop

Item.collection.insert( :type => "A", :pos => "First" )
Item.collection.insert( :type => "A", :pos => "Second"  )
Item.collection.insert( :type => "A", :pos => "Third" )
Item.collection.insert( :type => "A", :pos => "Forth" )
Item.collection.insert( :type => "B", :pos => "First" )
Item.collection.insert( :type => "B", :pos => "Second" )
Item.collection.insert( :type => "B", :pos => "Third" )
Item.collection.insert( :type => "B", :pos => "Forth" )

res = Item.collection.aggregate([
  { "$group" => {
      "_id" => "$type",
      "docs" => {
        "$push" => {
          "pos" => "$pos", "type" => "$type"
        }
      },
      "one" => {
        "$first" => {
          "pos" => "$pos", "type" => "$type"
        }
      }
  }},
  { "$unwind" =>  "$docs" },
  { "$project" => {
    "docs" => {
      "pos" => "$docs.pos",
      "type" => "$docs.type",
      "seen" => {
        "$eq" => [ "$one", "$docs" ]
      },
    },
    "one" => 1
  }},
  { "$match" => {
    "docs.seen" => false
  }},
  { "$group" => {
    "_id" => "$_id",
    "one" => { "$first" => "$one" },
    "two" => {
      "$first" => {
        "pos" => "$docs.pos",
        "type" => "$docs.type"
      }
    },
    "splitter" => {
      "$first" => {
        "$literal" => ["one","two"]
      }
    }
  }},
  { "$unwind" => "$splitter" },
  { "$project" => {
    "_id" => 0,
    "type" => {
      "$cond" => [
        { "$eq" => [ "$splitter", "one" ] },
        "$one.type",
        "$two.type"
      ]
    },
    "pos" => {
      "$cond" => [
        { "$eq" => [ "$splitter", "one" ] },
        "$one.pos",
        "$two.pos"
      ]
    }
  }}
])

pp res

दस्तावेजों में नामकरण वास्तव में कोड द्वारा उपयोग नहीं किया जाता है, और "प्रथम", "द्वितीय" आदि के लिए दिखाए गए डेटा में शीर्षक वास्तव में केवल यह दर्शाने के लिए हैं कि आप वास्तव में सूची से "शीर्ष 2" दस्तावेज़ प्राप्त कर रहे हैं एक परिणाम।

तो यहां दृष्टिकोण अनिवार्य रूप से आपकी कुंजी द्वारा "समूहीकृत" दस्तावेज़ों का "स्टैक" बनाने के लिए है, जैसे "टाइप"। यहां सबसे पहली बात यह है कि $first ऑपरेटर।

बाद के चरण स्टैक से "देखे गए" तत्वों से मेल खाते हैं और उन्हें फ़िल्टर करते हैं, फिर आप $first ऑपरेटर। इनपुट में पाए जाने वाले दस्तावेजों को मूल रूप में वापस करने के लिए अंतिम चरण वास्तव में जस्ट एक्स हैं, जो आम तौर पर ऐसी क्वेरी से अपेक्षित होता है।

तो परिणाम निश्चित रूप से है, प्रत्येक प्रकार के लिए केवल शीर्ष 2 दस्तावेज़:

{ "type"=>"A", "pos"=>"First" }
{ "type"=>"A", "pos"=>"Second" }
{ "type"=>"B", "pos"=>"First" }
{ "type"=>"B", "pos"=>"Second" }

इस हालिया उत्तर में इसके साथ-साथ अन्य समाधानों की लंबी चर्चा और संस्करण भी था:

मोंगोडब एग्रीगेशन $group, एरे की लंबाई सीमित करें

शीर्षक के बावजूद अनिवार्य रूप से वही बात और वह मामला 10 शीर्ष प्रविष्टियों या उससे अधिक से मेल खाना चाहता था। बड़े मैचों के साथ-साथ कुछ वैकल्पिक तरीकों से निपटने के लिए वहां कुछ पाइपलाइन जनरेशन कोड भी हैं, जिन पर आपके डेटा के आधार पर विचार किया जा सकता है।



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. मोंगोडब और पाइमोंगो में खाली स्ट्रिंग का परीक्षण करें

  2. क्या मोंगो एएससी क्रम में अंत में खाली/गायब फ़ील्ड वाले दस्तावेज़ वापस कर सकता है?

  3. उप-दस्तावेज़ को क्वेरी करना और केवल मिलान करने वाले उप-दस्तावेज़ को वापस करना

  4. MongoDB एटलस का उपयोग करते समय mongo-go-driver सर्वर चयन टाइमआउट के साथ विफल रहता है

  5. mgo क्वेरी से ObjectIdHex मान प्राप्त करें