মঙ্গোডিবি: একাধিক সংগ্রহ থেকে ডেটা একত্রিত করুন..কীভাবে?


229

আমি কীভাবে (মঙ্গোডিবিতে) একাধিক সংগ্রহের ডেটা এক সংগ্রহে একত্রিত করতে পারি?

আমি কি মানচিত্র-হ্রাস ব্যবহার করতে পারি এবং যদি তাই হয় তবে কীভাবে?

আমি একজন নবাগত হিসাবে আমি কিছু উদাহরণের প্রশংসা করব।


18
আপনি কি বিভিন্ন সংগ্রহ থেকে ডক্সকে কেবল একটি একক সংগ্রহের অনুলিপি করতে চান বা আপনার পরিকল্পনা কী? আপনি "সংহত" নির্দিষ্ট করতে পারেন? আপনি যদি কেবল মঙ্গো শেলের মাধ্যমে অনুলিপি করতে চান তবে db.collection1.find().forEach(function(doc){db.collection2.save(doc)});এটি যথেষ্ট। আপনি যদি মঙ্গো শেল ব্যবহার না করেন তবে দয়া করে আপনার ব্যবহৃত ড্রাইভার (জাভা, পিএইচপি, ...) নির্দিষ্ট করুন।
প্রক্সিমাস

সুতরাং আমার কাছে অন্যান্য সংগ্রহগুলির চেয়ে অ্যাড্রেস বুক সংগ্রহ, বই সংগ্রহের তালিকা ইত্যাদির তুলনায় একটি সংগ্রহ রয়েছে (ব্যবহারকারী বলুন) etc. আমি কীভাবে ইউজার_আইডি কী এর ভিত্তিতে এই সংগ্রহগুলিকে কেবল একটি একক সংকলনে একত্রিত করতে পারি? ?
ব্যবহারকারী 697697

উত্তর:


147

যদিও আপনি এই রিয়েল-টাইমটি করতে পারবেন না, আপনি মংগোডিবি 1.8+ মানচিত্র / হ্রাসে "হ্রাস" বিকল্পটি ব্যবহার করে একসাথে ডেটা একত্রিত করতে মানচিত্র-হ্রাস একাধিকবার চালাতে পারেন (দেখুন http://www.mongodb.org/ ডিসপ্লে / ডকস / ম্যাপ্রেডস # ম্যাপ্রেডস-আউটপুটপশনস )। উভয় সংগ্রহে আপনার কিছু কী থাকা দরকার যা আপনি _আইডি হিসাবে ব্যবহার করতে পারেন।

উদাহরণস্বরূপ, আসুন আমরা বলি যে আপনার কাছে একটি usersসংগ্রহ এবং commentsসংগ্রহ রয়েছে এবং আপনার একটি নতুন সংগ্রহ থাকতে চান যাতে প্রতিটি মন্তব্যের জন্য কিছু ব্যবহারকারী ডেমোগ্রাফিক তথ্য রয়েছে।

ধরা যাক usersসংগ্রহের নিম্নলিখিত ক্ষেত্রগুলি রয়েছে:

  • _id
  • নামের প্রথম অংশ
  • নামের শেষাংশ
  • দেশ
  • লিঙ্গ
  • বয়স

এবং তারপরে commentsসংগ্রহের নিম্নলিখিত ক্ষেত্রগুলি রয়েছে:

  • _id
  • ব্যবহারকারী আইডি
  • মন্তব্য
  • নির্মিত

আপনি এই মানচিত্রটি / হ্রাস করতে হবে:

var mapUsers, mapComments, reduce;
db.users_comments.remove();

// setup sample data - wouldn't actually use this in production
db.users.remove();
db.comments.remove();
db.users.save({firstName:"Rich",lastName:"S",gender:"M",country:"CA",age:"18"});
db.users.save({firstName:"Rob",lastName:"M",gender:"M",country:"US",age:"25"});
db.users.save({firstName:"Sarah",lastName:"T",gender:"F",country:"US",age:"13"});
var users = db.users.find();
db.comments.save({userId: users[0]._id, "comment": "Hey, what's up?", created: new ISODate()});
db.comments.save({userId: users[1]._id, "comment": "Not much", created: new ISODate()});
db.comments.save({userId: users[0]._id, "comment": "Cool", created: new ISODate()});
// end sample data setup

mapUsers = function() {
    var values = {
        country: this.country,
        gender: this.gender,
        age: this.age
    };
    emit(this._id, values);
};
mapComments = function() {
    var values = {
        commentId: this._id,
        comment: this.comment,
        created: this.created
    };
    emit(this.userId, values);
};
reduce = function(k, values) {
    var result = {}, commentFields = {
        "commentId": '', 
        "comment": '',
        "created": ''
    };
    values.forEach(function(value) {
        var field;
        if ("comment" in value) {
            if (!("comments" in result)) {
                result.comments = [];
            }
            result.comments.push(value);
        } else if ("comments" in value) {
            if (!("comments" in result)) {
                result.comments = [];
            }
            result.comments.push.apply(result.comments, value.comments);
        }
        for (field in value) {
            if (value.hasOwnProperty(field) && !(field in commentFields)) {
                result[field] = value[field];
            }
        }
    });
    return result;
};
db.users.mapReduce(mapUsers, reduce, {"out": {"reduce": "users_comments"}});
db.comments.mapReduce(mapComments, reduce, {"out": {"reduce": "users_comments"}});
db.users_comments.find().pretty(); // see the resulting collection

এই মুহুর্তে, আপনার কাছে একটি নতুন সংগ্রহ বলা users_commentsহবে যার মধ্যে মার্জড ডেটা রয়েছে এবং আপনি এখন এটি ব্যবহার করতে পারেন। এই হ্রাস সংগ্রহগুলি হ'ল _idযা আপনার মানচিত্রের ক্রিয়াকলাপগুলিতে আপনি কীটি বেরিয়েছিলেন এবং তারপরে সমস্ত মানগুলি valueকী এর অভ্যন্তরীণ একটি সাব-অবজেক্ট - মানগুলি হ্রাস হওয়া নথির শীর্ষ স্তরে নয়।

এটি কিছুটা সহজ উদাহরণ। আপনি হ্রাস সংগ্রহটি আরও বাড়িয়ে তুলতে চাইলে আরও সংগ্রহের সাথে এটি পুনরাবৃত্তি করতে পারেন। প্রক্রিয়াটিতে আপনি সংক্ষিপ্তসার এবং ডেটা একত্রিত করতে পারেন। বিদ্যমান ক্ষেত্রগুলিকে একত্রিত ও সংরক্ষণের জন্য যুক্তি আরও জটিল হয়ে যাওয়ার কারণে আপনি একাধিক ফাংশন হ্রাসের সংজ্ঞা দিবেন।

আপনি আরও লক্ষ করতে পারেন যে অ্যারেতে ব্যবহারকারীর সমস্ত মন্তব্য সহ প্রতিটি ব্যবহারকারীর জন্য এখন একটি নথি রয়েছে। যদি আমরা ডেটা মার্জ করে থাকি যা একের সাথে একের চেয়ে অনেকের মধ্যে এক-একের সম্পর্ক থাকে তবে এটি সমতল হবে এবং আপনি কেবল এই জাতীয়ভাবে হ্রাসকরণের ক্রিয়াটি ব্যবহার করতে পারেন:

reduce = function(k, values) {
    var result = {};
    values.forEach(function(value) {
        var field;
        for (field in value) {
            if (value.hasOwnProperty(field)) {
                result[field] = value[field];
            }
        }
    });
    return result;
};

আপনি যদি users_commentsসংগ্রহটি চ্যাপ্টা করতে চান তবে এটি মন্তব্যের জন্য একটি ডকুমেন্ট, অতিরিক্তভাবে এটি চালান:

var map, reduce;
map = function() {
    var debug = function(value) {
        var field;
        for (field in value) {
            print(field + ": " + value[field]);
        }
    };
    debug(this);
    var that = this;
    if ("comments" in this.value) {
        this.value.comments.forEach(function(value) {
            emit(value.commentId, {
                userId: that._id,
                country: that.value.country,
                age: that.value.age,
                comment: value.comment,
                created: value.created,
            });
        });
    }
};
reduce = function(k, values) {
    var result = {};
    values.forEach(function(value) {
        var field;
        for (field in value) {
            if (value.hasOwnProperty(field)) {
                result[field] = value[field];
            }
        }
    });
    return result;
};
db.users_comments.mapReduce(map, reduce, {"out": "comments_with_demographics"});

এই কৌশলটি অবশ্যই উড়ে যাওয়া উচিত নয়। এটি ক্রোন চাকরির মতো বা এমন কোনও কিছুর জন্য উপযুক্ত যা মেশানো ডেটা পর্যায়ক্রমে আপডেট করে। আপনি সম্ভবত ensureIndexএই সংগ্রহের বিরুদ্ধে আপনি যে অনুসন্ধানগুলি করেছেন তা নিশ্চিত করার জন্য আপনি নতুন সংগ্রহটি চালিয়ে যেতে চাইবেন (মনে রাখবেন যে আপনার ডেটা এখনও একটি valueচাবির মধ্যে রয়েছে তাই comments_with_demographicsমন্তব্যটির createdসময় যদি আপনি সূচী হয়ে থাকেন তবে এটি হবেdb.comments_with_demographics.ensureIndex({"value.created": 1});


1
আমি সম্ভবত প্রোডাকশন সফটওয়্যারটিতে এটি কখনই করব না, তবে এটি এখনও একটি দুষ্ট শান্ত কৌশল।
ডেভ গ্রিফিথ

3
ধন্যবাদ, ডেভ আমি গত তিন মাস ধরে ইস্যু ছাড়াই উত্পাদনে উচ্চ ট্র্যাফিক সাইটের জন্য রফতানি তৈরি এবং টেবিলগুলি প্রতিবেদন করার জন্য এই কৌশলটি ব্যবহার করেছি। এখানে আরও একটি নিবন্ধ যা কৌশলটির অনুরূপ ব্যবহারের বর্ণনা দেয়: tebros.com/2011/07/…
rmarscher

1
ধন্যবাদ @ রমার্সার আপনার অতিরিক্ত বিশদটি আমাকে সবকিছু আরও ভালভাবে বুঝতে সাহায্য করেছে।
বেন্ত্রি

5
আমার এই উত্তরটি একীকরণ পাইপলাইন এবং নতুন $ লুকিং অপারেশন ব্যবহার করে একটি উদাহরণ সহ আপডেট করা উচিত। আমি এখানে যথাযথ লেখার ব্যবস্থা না করা পর্যন্ত এটি উল্লেখ করে। docs.mongodb.org/manual/references/operator/aggregation/lookup
rmarscher


127

মঙ্গোডিবি ৩.২ এখন একজনকে একাধিক সংগ্রহ থেকে ডেটা একত্রিত করার অনুমতি দেয় $ লুকিং অগ্রিগেশন পর্যায়ে । ব্যবহারিক উদাহরণ হিসাবে, আসুন আমরা বলতে পারি যে আপনার কাছে বইগুলি সম্পর্কিত দুটি তথ্য দুটি পৃথক সংকলনে বিভক্ত।

booksনিম্নলিখিত সংগ্রহ সহ প্রথম সংগ্রহ, বলা হচ্ছে:

{
    "isbn": "978-3-16-148410-0",
    "title": "Some cool book",
    "author": "John Doe"
}
{
    "isbn": "978-3-16-148999-9",
    "title": "Another awesome book",
    "author": "Jane Roe"
}

এবং দ্বিতীয় সংকলন, যার books_selling_dataমধ্যে নিম্নলিখিত ডেটা রয়েছে:

{
    "_id": ObjectId("56e31bcf76cdf52e541d9d26"),
    "isbn": "978-3-16-148410-0",
    "copies_sold": 12500
}
{
    "_id": ObjectId("56e31ce076cdf52e541d9d28"),
    "isbn": "978-3-16-148999-9",
    "copies_sold": 720050
}
{
    "_id": ObjectId("56e31ce076cdf52e541d9d29"),
    "isbn": "978-3-16-148999-9",
    "copies_sold": 1000
}

উভয় সংগ্রহকে একত্রিত করা কেবলমাত্র নিম্নলিখিত পদ্ধতিতে $ দেখার জন্য বিষয়:

db.books.aggregate([{
    $lookup: {
            from: "books_selling_data",
            localField: "isbn",
            foreignField: "isbn",
            as: "copies_sold"
        }
}])

এই সংগ্রহের পরে, booksসংগ্রহটি নিম্নলিখিতগুলির মতো দেখাবে:

{
    "isbn": "978-3-16-148410-0",
    "title": "Some cool book",
    "author": "John Doe",
    "copies_sold": [
        {
            "_id": ObjectId("56e31bcf76cdf52e541d9d26"),
            "isbn": "978-3-16-148410-0",
            "copies_sold": 12500
        }
    ]
}
{
    "isbn": "978-3-16-148999-9",
    "title": "Another awesome book",
    "author": "Jane Roe",
    "copies_sold": [
        {
            "_id": ObjectId("56e31ce076cdf52e541d9d28"),
            "isbn": "978-3-16-148999-9",
            "copies_sold": 720050
        },
        {
            "_id": ObjectId("56e31ce076cdf52e541d9d28"),
            "isbn": "978-3-16-148999-9",
            "copies_sold": 1000
        }
    ]
}

কয়েকটি বিষয় লক্ষ্য করা গুরুত্বপূর্ণ:

  1. এই ক্ষেত্রে "থেকে" সংগ্রহটি books_selling_dataতীক্ষ্ণ করা যায় না।
  2. উপরের উদাহরণ হিসাবে "হিসাবে" ক্ষেত্রটি একটি অ্যারে হবে।
  3. $ অনুসন্ধানের পর্যায়ে উভয় "লোকালফিল্ড" এবং "বিদেশী ফিল্ড" বিকল্পগুলি যদি তাদের নিজ নিজ সংগ্রহগুলিতে উপস্থিত না থাকে তবে মেলানো উদ্দেশ্যগুলির জন্য নাল হিসাবে বিবেচিত হবে ( $ লুকিং ডকস সম্পর্কে এটির একটি নিখুঁত উদাহরণ রয়েছে)।

সুতরাং, উপসংহার হিসাবে, যদি আপনি উভয় সংগ্রহকে একত্রীকরণ করতে চান, এই ক্ষেত্রে মোট বিক্রয়কৃত অনুলিপি সহ একটি সমতল অনুলিপি বিক্রয় ক্ষেত্র, আপনাকে আরও কিছুটা কাজ করতে হবে, সম্ভবত কোনও মধ্যস্থতাকারী সংগ্রহ ব্যবহার করে, তারপর, হতে $ আউট চূড়ান্ত সংগ্রহে।


হাই, দয়া করে আপনি বলতে পারেন যে এর মতো ডেটা পরিচালনা করার অনুকূল উপায় কী হবে: ব্যবহারকারী, ফাইল.ফাইল এবং ফাইল.চাঁকস তিনটি সংগ্রহ, আমি প্রতিক্রিয়াতে এর সাথে সম্পর্কিত সমস্ত ফাইল সহ সুনির্দিষ্ট ব্যবহারকারীকে চাই এটি কি সম্ভব? " name "নাম": "ব্যাটম্যান", "ইমেল": "বিটি@gmail.com", "ফাইলগুলি": [{file1}, {file2}, {ফাইল3}, .... তাই]]
m

উপরের সমাধানের জন্য অফিসিয়াল ডকুমেন্টেশনের উদাহরণগুলি এখানে পাওয়া যাবে: ডকস.মংডব.কম
জাকুব জাজপ্লিকি

4
ঠিক আছে, আসলে আমার উত্তরটির অফিসিয়াল ডকুমেন্টেশনের সাথে ইতিমধ্যে তিনটি লিঙ্ক রয়েছে। তবে যাইহোক আপনার অবদানের জন্য ধন্যবাদ। @ জাকুবজাপ্লিক্লি
ব্রুনো ক্রেবস

2
আমার মোট মস্তিষ্কের ত্রুটি হতে পারে (সম্ভবতঃ) তবে এর মধ্যে $lookupসমস্ত "লোকালফিল্ড" এবং "বিদেশী ফিল্ড" সমান "ইসবিএন" হওয়া উচিত নয়? "_আইডি" এবং "ইসবিএন" নয়?
Dev01

13

যদি মংডোবগুলিতে কোনও বাল্ক isোকানো না থাকে তবে আমরা সমস্ত বস্তু লুপ করি এবং সেগুলির মধ্যে small_collectionএকটি করে একটি প্রবেশ করান big_collection:

db.small_collection.find().forEach(function(obj){ 
   db.big_collection.insert(obj)
});

db.colleciton.insert ([{}, {}, {}]) সন্নিবেশ করা অ্যারে গ্রহণ করে।
augurone

2
এটি ছোট সংগ্রহের জন্য দুর্দান্ত কাজ করে তবে সূচী স্থানান্তর করতে ভুলবেন না :)
সেবাস্তিয়ান লরবার

12

$ দর্শন সহ খুব বুনিয়াদী উদাহরণ।

db.getCollection('users').aggregate([
    {
        $lookup: {
            from: "userinfo",
            localField: "userId",
            foreignField: "userId",
            as: "userInfoData"
        }
    },
    {
        $lookup: {
            from: "userrole",
            localField: "userId",
            foreignField: "userId",
            as: "userRoleData"
        }
    },
    { $unwind: { path: "$userInfoData", preserveNullAndEmptyArrays: true }},
    { $unwind: { path: "$userRoleData", preserveNullAndEmptyArrays: true }}
])

এখানে ব্যবহৃত হয়

 { $unwind: { path: "$userInfoData", preserveNullAndEmptyArrays: true }}, 
 { $unwind: { path: "$userRoleData", preserveNullAndEmptyArrays: true }}

পরিবর্তে

{ $unwind:"$userRoleData"} 
{ $unwind:"$userRoleData"}

কারণ $ w আনওয়াইন্ড: "$ ইউজাররোলডেটা"} empty লুকিংয়ের সাথে কোনও মিলের রেকর্ড না পাওয়া গেলে এটি খালি বা 0 ফলাফল ফিরে আসবে।


11

একটি 'এসকিউএল ইউনিয়ন' ফ্যাশনে মংগোডিবিতে ইউনিয়নগুলি করা একক ক্যোয়ারিতে লুকআপের পাশাপাশি সমষ্টিগুলি ব্যবহার করা সম্ভব। এখানে আমি উদাহরণ দিয়ে দেখেছি যা মঙ্গোডিবি ৪.০ এর সাথে কাজ করে:

// Create employees data for testing the union.
db.getCollection('employees').insert({ name: "John", type: "employee", department: "sales" });
db.getCollection('employees').insert({ name: "Martha", type: "employee", department: "accounting" });
db.getCollection('employees').insert({ name: "Amy", type: "employee", department: "warehouse" });
db.getCollection('employees').insert({ name: "Mike", type: "employee", department: "warehouse"  });

// Create freelancers data for testing the union.
db.getCollection('freelancers').insert({ name: "Stephany", type: "freelancer", department: "accounting" });
db.getCollection('freelancers').insert({ name: "Martin", type: "freelancer", department: "sales" });
db.getCollection('freelancers').insert({ name: "Doug", type: "freelancer", department: "warehouse"  });
db.getCollection('freelancers').insert({ name: "Brenda", type: "freelancer", department: "sales"  });

// Here we do a union of the employees and freelancers using a single aggregation query.
db.getCollection('freelancers').aggregate( // 1. Use any collection containing at least one document.
  [
    { $limit: 1 }, // 2. Keep only one document of the collection.
    { $project: { _id: '$$REMOVE' } }, // 3. Remove everything from the document.

    // 4. Lookup collections to union together.
    { $lookup: { from: 'employees', pipeline: [{ $match: { department: 'sales' } }], as: 'employees' } },
    { $lookup: { from: 'freelancers', pipeline: [{ $match: { department: 'sales' } }], as: 'freelancers' } },

    // 5. Union the collections together with a projection.
    { $project: { union: { $concatArrays: ["$employees", "$freelancers"] } } },

    // 6. Unwind and replace root so you end up with a result set.
    { $unwind: '$union' },
    { $replaceRoot: { newRoot: '$union' } }
  ]);

এটি কীভাবে কাজ করে তার ব্যাখ্যা এখানে:

  1. আপনার ডাটাবেসের যে কোনও সংকলনের মধ্যে কমপক্ষে একটি ডকুমেন্ট রয়েছে তার aggregateবাইরে ইনস্টল করুন । যদি আপনি গ্যারান্টি দিতে না পারেন যে আপনার ডাটাবেসের কোনও সংগ্রহ খালি না থেকে থাকে, আপনি আপনার ডাটাবেসে কোনও ধরণের 'ডামি' সংগ্রহ তৈরি করে এটিতে একক খালি নথি যা বিশেষত ইউনিয়ন কোয়েরি করার জন্য থাকবে তা সমাধান করতে পারেন।

  2. আপনার পাইপলাইনটি প্রথম পর্যায়ে পরিণত করুন { $limit: 1 }। এটি প্রথমটি বাদে সংগ্রহের সমস্ত নথি ছড়িয়ে দেবে।

  3. এটিকে ব্যবহার করে বাকী নথির সমস্ত ক্ষেত্র স্ট্রিপ করুন $project স্টেজ :

    { $project: { _id: '$$REMOVE' } }
  4. আপনার সামগ্রীতে এখন একটি একক, খালি দস্তাবেজ রয়েছে। আপনি একসাথে ইউনিয়ন করতে চান এমন প্রতিটি সংগ্রহের জন্য অনুসন্ধানগুলি যুক্ত করার সময়। আপনি pipelineনির্দিষ্ট ফিল্টারিং করতে ক্ষেত্রটি ব্যবহার করতে পারেন , বা ছেড়ে যান localFieldএবংforeignField পুরো সংগ্রহের সাথে মেলে নাল হিসাবে।

    { $lookup: { from: 'collectionToUnion1', pipeline: [...], as: 'Collection1' } },
    { $lookup: { from: 'collectionToUnion2', pipeline: [...], as: 'Collection2' } },
    { $lookup: { from: 'collectionToUnion3', pipeline: [...], as: 'Collection3' } }
  5. আপনার কাছে এখন একটি একক দস্তাবেজ সমন্বিত রয়েছে যাতে এতে 3 টি অ্যারে থাকে:

    {
        Collection1: [...],
        Collection2: [...],
        Collection3: [...]
    }

    তারপরে আপনি এগ্রিগেশন অপারেটরের $projectসাথে একটি মঞ্চ ব্যবহার করে তাদের একত্রে অ্যারেতে একত্রে মার্জ করতে পারেন $concatArrays:

    {
      "$project" :
      {
        "Union" : { $concatArrays: ["$Collection1", "$Collection2", "$Collection3"] }
      }
    }
  6. এখন আপনার কাছে একটি একক দস্তাবেজ সমন্বিত রয়েছে, এতে একটি সংগ্রহস্থল রয়েছে যা আপনার সংগ্রহের ইউনিয়ন ধারণ করে। যা করা বাকি তা হ'ল আপনার অ্যারেটিকে পৃথক নথিতে বিভক্ত করার জন্য একটি $unwindএবং একটি $replaceRootমঞ্চ যুক্ত করা:

    { $unwind: "$Union" },
    { $replaceRoot: { newRoot: "$Union" } }
  7. Voila। আপনি এখন একসাথে একত্রিত করতে চেয়েছিলেন এমন সংগ্রহগুলি সহ একটি ফলাফল সেট রয়েছে। এরপরে আপনি এটিকে আরও ফিল্টার করতে আরও ধাপ যুক্ত করতে পারেন, এটি বাছাই করতে পারেন, স্কিপ প্রয়োগ করুন () এবং সীমাবদ্ধ করুন ()। আপনি চান অনেক সুন্দর।


"$ অভিক্ষেত্রে কমপক্ষে একটি আউটপুট ক্ষেত্র প্রয়োজন" বার্তাটি দিয়ে কোয়েরি ব্যর্থ হচ্ছে।
অভিষেক_গন্ত

@ অভিষেক যদি আপনি এটি পান তবে আপনি একক প্রজেকশন পর্যায়ে সমস্ত ক্ষেত্রকে একক দস্তাবেজ থেকে সরিয়ে দেওয়ার চেষ্টা করেছেন। মঙ্গোডিবি আপনাকে এটি করতে দেবে না। এটি কার্যকর করার জন্য আপনাকে একের পর এক 2 টি অনুমান করতে হবে যেখানে প্রথমটি _ _id ব্যতীত সমস্ত কিছু ফেলে দেয় এবং দ্বিতীয়টি বাকী _idটি ফেলে দেয়।
sboisse

@ অভিষেক আমি '$ সরান' ভেরিয়েবল ব্যবহার করে এমন একক ক্ষেত্রে stages প্রকল্পের পর্যায়ে প্রতিস্থাপন করে আরও ক্যোয়ারী আরও সহজ করেছি। আমি একটি কংক্রিট উদাহরণও যুক্ত করেছি যে আপনি কেবল আপনার ক্যোয়ারী পরীক্ষককে এটির কাজ করে তা সরাসরি কপি এবং পেস্ট করতে পারেন।
sboisse

@ সোবাইস, এই সমাধানটি ছোট সংগ্রহের জন্য কাজ করে, তবে, যদি আমি এটি বড় সংগ্রহগুলিতে করতে চাই, (100,000+ ডক্স), আমি একটি "সংগ্রহের সম্পূর্ণ নথির আকারে চলে যাই .ToUnion1 সর্বোচ্চ নথির আকার ছাড়িয়ে গেছে" ce দস্তাবেজগুলিতে, এটি বৃহত্তর মধ্যবর্তী নথিগুলি এড়াতে $ লুকের পরে সরাসরি একটি আনওয়াইন্ড রাখার পরামর্শ দেয়। আমি সেই পদ্ধতিটি ব্যবহার করে এই সমাধানটি সংশোধন করতে সফল হইনি। আপনি কি এই সমস্যাটিতে চলে এসেছেন এবং সেই পদ্ধতিটি ব্যবহার করতে হয়েছিল? আমি যে দস্তাবেজগুলিকে প্রত্যাখ্যান করছি তার সাথে লিঙ্ক করুন: [লিঙ্ক] ( ডকস.মোংডব.কম্যানুয়াল
কোর

@ ভাগ্যবান amsস্যামসন দুর্ভাগ্যক্রমে আমার যে পরিমাণ ডেটা মোকাবেলা করতে হয়েছে তা এত বড় ছিল না। সুতরাং আপনি যে সমস্যার উল্লেখ করছেন তাতে আমার মুখোমুখি হতে হয়নি। আমার ক্ষেত্রে আমি বাকীগুলির সাথে রেকর্ড একীভূত করার আগে সংগ্রহের জন্য ফিল্টারিং প্রয়োগ করতে পারি, সুতরাং ইউনিয়নে ডেটা পরিমাণ ছিল খুব কম।
sboisse

9

একত্রে একাধিক সংগ্রহের জন্য একাধিক $ অনুসন্ধান ব্যবহার করুন

প্রশ্ন:

db.getCollection('servicelocations').aggregate([
  {
    $match: {
      serviceLocationId: {
        $in: ["36728"]
      }
    }
  },
  {
    $lookup: {
      from: "orders",
      localField: "serviceLocationId",
      foreignField: "serviceLocationId",
      as: "orders"
    }
  },
  {
    $lookup: {
      from: "timewindowtypes",
      localField: "timeWindow.timeWindowTypeId",
      foreignField: "timeWindowTypeId",
      as: "timeWindow"
    }
  },
  {
    $lookup: {
      from: "servicetimetypes",
      localField: "serviceTimeTypeId",
      foreignField: "serviceTimeTypeId",
      as: "serviceTime"
    }
  },
  {
    $unwind: "$orders"
  },
  {
    $unwind: "$serviceTime"
  },
  {
    $limit: 14
  }
])

ফলাফল:

{
    "_id" : ObjectId("59c3ac4bb7799c90ebb3279b"),
    "serviceLocationId" : "36728",
    "regionId" : 1.0,
    "zoneId" : "DXBZONE1",
    "description" : "AL HALLAB REST EMIRATES MALL",
    "locationPriority" : 1.0,
    "accountTypeId" : 1.0,
    "locationType" : "SERVICELOCATION",
    "location" : {
        "makani" : "",
        "lat" : 25.119035,
        "lng" : 55.198694
    },
    "deliveryDays" : "MTWRFSU",
    "timeWindow" : [ 
        {
            "_id" : ObjectId("59c3b0a3b7799c90ebb32cde"),
            "timeWindowTypeId" : "1",
            "Description" : "MORNING",
            "timeWindow" : {
                "openTime" : "06:00",
                "closeTime" : "08:00"
            },
            "accountId" : 1.0
        }, 
        {
            "_id" : ObjectId("59c3b0a3b7799c90ebb32cdf"),
            "timeWindowTypeId" : "1",
            "Description" : "MORNING",
            "timeWindow" : {
                "openTime" : "09:00",
                "closeTime" : "10:00"
            },
            "accountId" : 1.0
        }, 
        {
            "_id" : ObjectId("59c3b0a3b7799c90ebb32ce0"),
            "timeWindowTypeId" : "1",
            "Description" : "MORNING",
            "timeWindow" : {
                "openTime" : "10:30",
                "closeTime" : "11:30"
            },
            "accountId" : 1.0
        }
    ],
    "address1" : "",
    "address2" : "",
    "phone" : "",
    "city" : "",
    "county" : "",
    "state" : "",
    "country" : "",
    "zipcode" : "",
    "imageUrl" : "",
    "contact" : {
        "name" : "",
        "email" : ""
    },
    "status" : "ACTIVE",
    "createdBy" : "",
    "updatedBy" : "",
    "updateDate" : "",
    "accountId" : 1.0,
    "serviceTimeTypeId" : "1",
    "orders" : [ 
        {
            "_id" : ObjectId("59c3b291f251c77f15790f92"),
            "orderId" : "AQ18O1704264",
            "serviceLocationId" : "36728",
            "orderNo" : "AQ18O1704264",
            "orderDate" : "18-Sep-17",
            "description" : "AQ18O1704264",
            "serviceType" : "Delivery",
            "orderSource" : "Import",
            "takenBy" : "KARIM",
            "plannedDeliveryDate" : ISODate("2017-08-26T00:00:00.000Z"),
            "plannedDeliveryTime" : "",
            "actualDeliveryDate" : "",
            "actualDeliveryTime" : "",
            "deliveredBy" : "",
            "size1" : 296.0,
            "size2" : 3573.355,
            "size3" : 240.811,
            "jobPriority" : 1.0,
            "cancelReason" : "",
            "cancelDate" : "",
            "cancelBy" : "",
            "reasonCode" : "",
            "reasonText" : "",
            "status" : "",
            "lineItems" : [ 
                {
                    "ItemId" : "BNWB020",
                    "size1" : 15.0,
                    "size2" : 78.6,
                    "size3" : 6.0
                }, 
                {
                    "ItemId" : "BNWB021",
                    "size1" : 20.0,
                    "size2" : 252.0,
                    "size3" : 11.538
                }, 
                {
                    "ItemId" : "BNWB023",
                    "size1" : 15.0,
                    "size2" : 285.0,
                    "size3" : 16.071
                }, 
                {
                    "ItemId" : "CPMW112",
                    "size1" : 3.0,
                    "size2" : 25.38,
                    "size3" : 1.731
                }, 
                {
                    "ItemId" : "MMGW001",
                    "size1" : 25.0,
                    "size2" : 464.375,
                    "size3" : 46.875
                }, 
                {
                    "ItemId" : "MMNB218",
                    "size1" : 50.0,
                    "size2" : 920.0,
                    "size3" : 60.0
                }, 
                {
                    "ItemId" : "MMNB219",
                    "size1" : 50.0,
                    "size2" : 630.0,
                    "size3" : 40.0
                }, 
                {
                    "ItemId" : "MMNB220",
                    "size1" : 50.0,
                    "size2" : 416.0,
                    "size3" : 28.846
                }, 
                {
                    "ItemId" : "MMNB270",
                    "size1" : 50.0,
                    "size2" : 262.0,
                    "size3" : 20.0
                }, 
                {
                    "ItemId" : "MMNB302",
                    "size1" : 15.0,
                    "size2" : 195.0,
                    "size3" : 6.0
                }, 
                {
                    "ItemId" : "MMNB373",
                    "size1" : 3.0,
                    "size2" : 45.0,
                    "size3" : 3.75
                }
            ],
            "accountId" : 1.0
        }, 
        {
            "_id" : ObjectId("59c3b291f251c77f15790f9d"),
            "orderId" : "AQ137O1701240",
            "serviceLocationId" : "36728",
            "orderNo" : "AQ137O1701240",
            "orderDate" : "18-Sep-17",
            "description" : "AQ137O1701240",
            "serviceType" : "Delivery",
            "orderSource" : "Import",
            "takenBy" : "KARIM",
            "plannedDeliveryDate" : ISODate("2017-08-26T00:00:00.000Z"),
            "plannedDeliveryTime" : "",
            "actualDeliveryDate" : "",
            "actualDeliveryTime" : "",
            "deliveredBy" : "",
            "size1" : 28.0,
            "size2" : 520.11,
            "size3" : 52.5,
            "jobPriority" : 1.0,
            "cancelReason" : "",
            "cancelDate" : "",
            "cancelBy" : "",
            "reasonCode" : "",
            "reasonText" : "",
            "status" : "",
            "lineItems" : [ 
                {
                    "ItemId" : "MMGW001",
                    "size1" : 25.0,
                    "size2" : 464.38,
                    "size3" : 46.875
                }, 
                {
                    "ItemId" : "MMGW001-F1",
                    "size1" : 3.0,
                    "size2" : 55.73,
                    "size3" : 5.625
                }
            ],
            "accountId" : 1.0
        }, 
        {
            "_id" : ObjectId("59c3b291f251c77f15790fd8"),
            "orderId" : "AQ110O1705036",
            "serviceLocationId" : "36728",
            "orderNo" : "AQ110O1705036",
            "orderDate" : "18-Sep-17",
            "description" : "AQ110O1705036",
            "serviceType" : "Delivery",
            "orderSource" : "Import",
            "takenBy" : "KARIM",
            "plannedDeliveryDate" : ISODate("2017-08-26T00:00:00.000Z"),
            "plannedDeliveryTime" : "",
            "actualDeliveryDate" : "",
            "actualDeliveryTime" : "",
            "deliveredBy" : "",
            "size1" : 60.0,
            "size2" : 1046.0,
            "size3" : 68.0,
            "jobPriority" : 1.0,
            "cancelReason" : "",
            "cancelDate" : "",
            "cancelBy" : "",
            "reasonCode" : "",
            "reasonText" : "",
            "status" : "",
            "lineItems" : [ 
                {
                    "ItemId" : "MMNB218",
                    "size1" : 50.0,
                    "size2" : 920.0,
                    "size3" : 60.0
                }, 
                {
                    "ItemId" : "MMNB219",
                    "size1" : 10.0,
                    "size2" : 126.0,
                    "size3" : 8.0
                }
            ],
            "accountId" : 1.0
        }
    ],
    "serviceTime" : {
        "_id" : ObjectId("59c3b07cb7799c90ebb32cdc"),
        "serviceTimeTypeId" : "1",
        "serviceTimeType" : "nohelper",
        "description" : "",
        "fixedTime" : 30.0,
        "variableTime" : 0.0,
        "accountId" : 1.0
    }
}

1

ডেটাবেজে ইতিমধ্যে যা আছে তার উপরে মংগেরস্টোরের বৈশিষ্ট্য রয়েছে, সুতরাং এই আচরণটি দুটি সংগ্রহের সংমিশ্রণের জন্য ব্যবহার করা যেতে পারে:

  1. মংডাম্প্প সংগ্রহ 1
  2. collection2.rename (collection1)
  3. mongorestore

এটি এখনও চেষ্টা করে দেখেনি, তবে এটি মানচিত্রের চেয়ে দ্রুত সম্পাদন / পদ্ধতির হ্রাস পেতে পারে।


1

শুরু করে Mongo 4.4, আমরা নতুন সংযোজন $unionWithপর্যায়ে $groupএর নতুন $accumulatorঅপারেটরের সাথে মিলিত করে একত্রিতকরণ পাইপলাইনের মধ্যে এই যোগদানটি অর্জন করতে পারি :

// > db.users.find()
//   [{ user: 1, name: "x" }, { user: 2, name: "y" }]
// > db.books.find()
//   [{ user: 1, book: "a" }, { user: 1, book: "b" }, { user: 2, book: "c" }]
// > db.movies.find()
//   [{ user: 1, movie: "g" }, { user: 2, movie: "h" }, { user: 2, movie: "i" }]
db.users.aggregate([
  { $unionWith: "books"  },
  { $unionWith: "movies" },
  { $group: {
    _id: "$user",
    user: {
      $accumulator: {
        accumulateArgs: ["$name", "$book", "$movie"],
        init: function() { return { books: [], movies: [] } },
        accumulate: function(user, name, book, movie) {
          if (name) user.name = name;
          if (book) user.books.push(book);
          if (movie) user.movies.push(movie);
          return user;
        },
        merge: function(userV1, userV2) {
          if (userV2.name) userV1.name = userV2.name;
          userV1.books.concat(userV2.books);
          userV1.movies.concat(userV2.movies);
          return userV1;
        },
        lang: "js"
      }
    }
  }}
])
// { _id: 1, user: { books: ["a", "b"], movies: ["g"], name: "x" } }
// { _id: 2, user: { books: ["c"], movies: ["h", "i"], name: "y" } }
  • $unionWithইতিমধ্যে সমষ্টি পাইপলাইনে নথিগুলির মধ্যে প্রদত্ত সংগ্রহ থেকে রেকর্ড একত্রিত করে। 2 ইউনিয়ন পর্যায়ের পরে, আমরা পাইপলাইনের মধ্যে এইভাবে সমস্ত ব্যবহারকারী, বই এবং চলচ্চিত্রের রেকর্ড রাখি।

  • এরপরে আমরা অপারেটরটিকে দলবদ্ধ হওয়ার সাথে সাথে নথিগুলির কাস্টম সংশ্লেষের অনুমতি দিয়ে আইটেমগুলি $groupদ্বারা রেকর্ড $userএবং জমা করি $accumulator:

    • যে ক্ষেত্রগুলিতে আমরা জমা হতে আগ্রহী সেগুলি সংজ্ঞায়িত করা হয় accumulateArgs
    • init রাষ্ট্রটিকে সংজ্ঞায়িত করা হয় যা আমরা উপাদানগুলির গ্রুপ হিসাবে সঞ্চিত হবে।
    • accumulateফাংশন করণ পারবেন একটি রেকর্ড দিয়ে একটি কাস্টম কর্ম অর্ডার জমা রাষ্ট্র গড়ে তুলতে গোষ্ঠীবদ্ধ করা হচ্ছে। উদাহরণস্বরূপ, গোষ্ঠীভুক্ত আইটেমটির bookক্ষেত্রটি যদি সংজ্ঞায়িত করা থাকে তবে আমরা booksরাজ্যের অংশটি আপডেট করি ।
    • mergeদুটি অভ্যন্তরীণ রাজ্যের একত্রিত করতে ব্যবহৃত হয়। এটি কেবল তীক্ষ্ণ ক্লাস্টারগুলিতে চলমান সমাহারগুলির জন্য বা অপারেশন মেমরির সীমা ছাড়িয়ে গেলে ব্যবহৃত হয়।

4.2.6 সংস্করণ এর জন্য কি একই ধরণের আউটপুট পুনরুদ্ধার করা সম্ভব
নিক্সিত প্যাটেল

0

হ্যাঁ আপনি করতে পারেন: আমি আজ লিখেছি যে এই ইউটিলিটি ফাংশন নিন:

function shangMergeCol() {
  tcol= db.getCollection(arguments[0]);
  for (var i=1; i<arguments.length; i++){
    scol= db.getCollection(arguments[i]);
    scol.find().forEach(
        function (d) {
            tcol.insert(d);
        }
    )
  }
}

আপনি যে কোনও সংখ্যক সংগ্রহ এই ফাংশনে পাস করতে পারেন, প্রথমটি লক্ষ্যটিকে এক হতে চলেছে। বাকি সমস্ত সংগ্রহগুলি লক্ষ্যটিকে স্থানান্তরিত করার উত্স।


-1

টুকিটাকি সংকেতলিপি. এই সহ একটি স্ট্যাক ওভারফ্লোতে সৌজন্যে-একাধিক পোস্ট।

 db.cust.drop();
 db.zip.drop();
 db.cust.insert({cust_id:1, zip_id: 101});
 db.cust.insert({cust_id:2, zip_id: 101});
 db.cust.insert({cust_id:3, zip_id: 101});
 db.cust.insert({cust_id:4, zip_id: 102});
 db.cust.insert({cust_id:5, zip_id: 102});

 db.zip.insert({zip_id:101, zip_cd:'AAA'});
 db.zip.insert({zip_id:102, zip_cd:'BBB'});
 db.zip.insert({zip_id:103, zip_cd:'CCC'});

mapCust = function() {
    var values = {
        cust_id: this.cust_id
    };
    emit(this.zip_id, values);
};

mapZip = function() {
    var values = {
    zip_cd: this.zip_cd
    };
    emit(this.zip_id, values);
};

reduceCustZip =  function(k, values) {
    var result = {};
    values.forEach(function(value) {
    var field;
        if ("cust_id" in value) {
            if (!("cust_ids" in result)) {
                result.cust_ids = [];
            }
            result.cust_ids.push(value);
        } else {
    for (field in value) {
        if (value.hasOwnProperty(field) ) {
                result[field] = value[field];
        }
         };  
       }
      });
       return result;
};


db.cust_zip.drop();
db.cust.mapReduce(mapCust, reduceCustZip, {"out": {"reduce": "cust_zip"}});
db.zip.mapReduce(mapZip, reduceCustZip, {"out": {"reduce": "cust_zip"}});
db.cust_zip.find();


mapCZ = function() {
    var that = this;
    if ("cust_ids" in this.value) {
        this.value.cust_ids.forEach(function(value) {
            emit(value.cust_id, {
                zip_id: that._id,
                zip_cd: that.value.zip_cd
            });
        });
    }
};

reduceCZ = function(k, values) {
    var result = {};
    values.forEach(function(value) {
        var field;
        for (field in value) {
            if (value.hasOwnProperty(field)) {
                result[field] = value[field];
            }
        }
    });
    return result;
};
db.cust_zip_joined.drop();
db.cust_zip.mapReduce(mapCZ, reduceCZ, {"out": "cust_zip_joined"}); 
db.cust_zip_joined.find().pretty();


var flattenMRCollection=function(dbName,collectionName) {
    var collection=db.getSiblingDB(dbName)[collectionName];

    var i=0;
    var bulk=collection.initializeUnorderedBulkOp();
    collection.find({ value: { $exists: true } }).addOption(16).forEach(function(result) {
        print((++i));
        //collection.update({_id: result._id},result.value);

        bulk.find({_id: result._id}).replaceOne(result.value);

        if(i%1000==0)
        {
            print("Executing bulk...");
            bulk.execute();
            bulk=collection.initializeUnorderedBulkOp();
        }
    });
    bulk.execute();
};


flattenMRCollection("mydb","cust_zip_joined");
db.cust_zip_joined.find().pretty();

-2

আপনার অ্যাপ্লিকেশন স্তরে এটি করতে হবে। আপনি যদি একটি ওআরএম ব্যবহার করে থাকেন তবে এটি অন্যান্য সংগ্রহগুলিতে বিদ্যমান রেফারেন্সগুলি টানতে টীকাগুলি (বা অনুরূপ কিছু) ব্যবহার করতে পারে। আমি কেবল মরফিয়ার সাথে কাজ করেছি , এবং @Referenceজিজ্ঞাসা করা হলে টীকাগুলি রেফারেন্সড সত্তাটি নিয়ে আসে, তাই আমি কোডে এটি নিজেই করা এড়াতে সক্ষম হয়েছি।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.