MongoDB melakukan $match dengan dua nilai array input?

Di MongoDB, saya mencoba menulis kueri di mana saya memiliki dua array input Bills, Names yang pertama berisi billid dan yang kedua berisi nama orang. Kenyataannya juga Tagihan di indeks i dan Nama di indeks i adalah dokumen sebenarnya yang ingin kita cari di MongoDB.

Saya ingin menulis kueri sedemikian rupa sehingga Bills[i] = db_billid && Names[i] = db_name yang berarti saya ingin mengembalikan hasil di mana pada indeks tertentu billid dan nama cocok.

Saya berpikir untuk menggunakan $in tetapi masalahnya saya dapat menerapkan $in di Bills tetapi saya tidak tahu di indeks mana billid itu ditemukan.

{ $and: [{ billid: { $in: Bills } }, {name: Names[**index at which this bill is found]}] }

Adakah yang bisa membantu saya bagaimana saya bisa mengatasi ini ??

Skema MongoDB

var transactionsschema = new Schema({
    transactionid: {type: String},
    billid: {type: String},
    name: {type: String}
});

Contoh dokumen di MongoDB

{ _id: XXXXXXXXXXX, transactionid: 1, billid : bnb1234, name: "sudhanshu"}, { _id: XXXXXXXXXXX, transactionid: 2, billid : bnb1235, name: "michael"}, { _id: XXXXXXXXXXX, transactionid: 3, billid : bnb1236, name: "Morgot"}

Contoh array

Bills = ["bill1", "bill2", "bill3"], Names = ["name1", "name2", "name"]

Edit - Jika $in dapat bekerja dalam array objek maka saya dapat memiliki array objek dengan kunci sebagai billid dan nama

var arr = [{ billid: "bill1", "name": "name1"}, {billid: "bill2", "name": "name2"}, {billid: "bill3", "name": "name3" }]

Tapi masalahnya adalah bagaimana bisa meletakkan kueri di bawah ini

{ $and: [{ billid: { $in: arr.Bills } }, {name: arr.Names}] }


person Sudhanshu Gaur    schedule 17.06.2018    source sumber
comment
Bisakah Anda menambahkan contoh dokumen dan contoh Tagihan dan Nama?   -  person mickl    schedule 17.06.2018
comment
@mickl tunggu izinkan saya menambahkannya.   -  person Sudhanshu Gaur    schedule 17.06.2018
comment
@mickl Saya telah menambahkan contoh dokumen.   -  person Sudhanshu Gaur    schedule 17.06.2018


Jawaban (1)


Mengetahui bahwa bills unik tetapi names mungkin memiliki duplikat, Anda dapat menggunakan $ indexOfArray untuk mendapatkan indeks yang cocok dengan bill dan kemudian menggunakan indeks tersebut untuk membandingkan array names pada indeks yang dievaluasi (menggunakan $arrayElemAt untuk mengambil nilai). Anda juga harus memeriksa apakah nilai yang dikembalikan oleh $indexOfArray tidak sama dengan -1 (tidak cocok)

var bills = ["bnb1234", "bnb1235"];
var names = ["sudhanshu", "michael"];

db.col.aggregate([
    {
        $match: {
            $expr: {
                $and: [
                    { $ne: [{ $indexOfArray: [ bills, "$billid" ] }, -1] },
                    { $eq: ["$name", { $arrayElemAt: [ names, { $indexOfArray: [ bills, "$billid" ] } ] }] },
                ]
            }
        }
    }
])

alternatifnya $let dapat digunakan untuk menghindari duplikasi:

db.col.aggregate([
    {
        $match: {
            $expr: {
                $let: {
                    vars: { index: { $indexOfArray: [ bills, "$billid" ] } },
                    in: { $and: [ { $ne: [ "$$index", -1 ] }, { $eq: [ "$name", { $arrayElemAt: [ names, "$$index" ] }] }]}
                }
            }
        }
    }
])
person mickl    schedule 17.06.2018
comment
Misalkan saya memiliki dua pertanyaan bersarang, yang pertama milik saya dan yang kedua solusinya telah Anda berikan, seperti `$match: {$and: { Transactionid: 12345678}, { Your Query} }, sekarang apakah akan berfungsi? Apakah ini bersarang dengan benar atau tidak? - person Sudhanshu Gaur; 17.06.2018
comment
Anda dapat menambahkan lebih banyak ketentuan ke $match, seperti { $and: [ { $ne: ["$billIndex", -1] }, { $ne: ["$nameIndex", -1] }, { $eq: ["$billIndex", "$nameIndex"] }, { $eq: [ "$transactionId": 123 ] } ] } apakah itu yang Anda maksud? - person mickl; 17.06.2018
comment
Biarkan saja, hanya ingin bertanya karena Bills adalah bidang unik tetapi Names tidak demikian, misalkan Contoh DB adalah [{ billid : bnb1234, name: "michael"}, {billid : bnb1235, name: "michael"}] Bills = ["bnb1234", "bnb1235"] dan Names = ["michael", "michael"] Sekarang masalahnya adalah ketika Anda akan menggunakan $match untuk melihat indeks keduanya maka untuk indeks Nama yang pertama akan menjadi 1 dan indeks Tagihan akan menjadi 1 jadi cocok tetapi untuk yang kedua karena indeks Tagihan adalah 2 tetapi indeks Nama adalah 1, bukan 2(because Names are not unique). - person Sudhanshu Gaur; 17.06.2018
comment
Lalu bagaimana saya bisa mengatasi hal itu. Btw terima kasih telah membantu saya keluar dari sini hanya satu baris dekat dengan solusi :) - person Sudhanshu Gaur; 17.06.2018
comment
Baru saja menemukan solusinya :) ubah sedikit jawaban Anda, terima kasih banyak kawan. Solusinya sudah saya sebutkan di postingan, ubah jawaban Anda di sini agar saya bisa menerimanya (y). - person Sudhanshu Gaur; 17.06.2018
comment
@SudhanshuGaur baru saja mengedit jawaban saya yang bisa lebih mudah jika Anda menggunakan arrayElemAt. Periksa jawaban saya yang telah diedit - person mickl; 17.06.2018
comment
Kueri Anda mengembalikan semua bidang dengan name michael tetapi seharusnya hanya mengembalikan dua dokumen. - person Sudhanshu Gaur; 17.06.2018
comment
Kedua solusi tersebut hampir sama, Anda hanya tidak menggunakan addFields, Ketika kami menambahkanFields apakah itu membuat kueri agak lambat? Karena bahkan di dalam kueri Anda ketika Anda akan menggunakan names dan bills itu juga akan menyiratkan hal yang sama? - person Sudhanshu Gaur; 17.06.2018
comment
Terima kasih bdw tanpamu itu tidak mungkin :) - person Sudhanshu Gaur; 17.06.2018