Pertanyaan MongoDB: beberapa $ elemMatch


Saya memiliki dokumen MongoDB yang terstruktur seperti ini:

{_id: ObjectId("53d760721423030c7e14266f"),
fruit: 'apple',
vitamins: [
    {
     _id: 1,
     name: 'B7',
     usefulness: 'useful',
     state: 'free',
    }
    {
     _id: 2,
     name: 'A1',
     usefulness: 'useful',
     state: 'free',
    }
    {
     _id: 3,
     name: 'A1',
     usefulness: 'useful',
     state: 'non_free',
    }
  ]
}
{_id: ObjectId("53d760721423030c7e142670"),
fruit: 'grape',
vitamins: [
    {
     _id: 4,
     name: 'B6',
     usefulness: 'useful',
     state: 'free',
    }
    {
     _id: 5,
     name: 'A1',
     usefulness: 'useful',
     state: 'non_free',
    }
    {
     _id: 6,
     name: 'Q5',
     usefulness: 'non_useful',
     state: 'non_free',
    }
  ]
}

Saya ingin bertanya dan mendapatkan semua buah yang memiliki keduanya {name: 'A1', state: 'non_free'} dan {name: 'B7', state: 'free'}. Dalam kasus terburuk saya ingin setidaknya menghitung entri ini jika mendapatkan mereka tidak mungkin dan jika kode yang setara ada untuk pymongo, untuk mengetahui bagaimana cara menulisnya.

Untuk contoh yang diberikan saya hanya ingin mengambil dokumen apel (pertama).

Jika saya gunakan $elemMatch itu hanya berfungsi untuk satu kondisi, tetapi tidak untuk keduanya. Misalnya. jika saya query find({'vitamins': {'$elemMatch': {'name': 'A1', 'state': 'non_free'}, '$elemMatch': {'name': 'B7', 'state': 'free'}}}) itu akan mengambil semua buah dengan {'name': 'B7', 'state': 'free'}.


9
2017-07-29 11:54


asal


Jawaban:


Dalam hal ini Anda bisa menggunakan $and-operator .

Coba kueri ini:

find({
    $and: [
         {'vitamins': {'$elemMatch': {'name': 'A1', 'state': 'non_free'} } },
         {'vitamins': {'$elemMatch': {'name': 'B7', 'state': 'free'} } }
    ]
});

Untuk menjelaskan mengapa Anda hanya menerima hasil yang cocok dengan kriteria kedua: Objek-objek di dalam masing-masing {} Anda lolos ke MongoDB adalah pasangan kunci / nilai. Setiap kunci hanya bisa ada satu kali per objek. Saat Anda mencoba menetapkan nilai ke kunci yang sama dua kali, penugasan kedua akan menimpa yang pertama. Dalam kasus Anda, Anda menetapkan dua nilai yang berbeda ke kunci $elemMatch di objek yang sama, jadi yang pertama diabaikan. Permintaan yang benar-benar tiba di MongoDB adalah adil find({'vitamins': {'$elemMatch': {'name': 'B7', 'state': 'free'}}}).

Kapanpun Anda perlu menerapkan operator yang sama ke tombol yang sama dua kali, Anda perlu menggunakannya $or atau $and.


17
2017-07-29 13:10



var fruits = db.fruits.find({
    "vitamins": {
        $all: [{
            $elemMatch: {
                "name": "A1",
                "state": "non_free"
            }
        }, {
            $elemMatch: {
                "name": "B7",
                "state": "free"
            }
        }]
    }
})

3
2017-07-29 13:30