MongoDB: How to find out if an array field contains an element?

前端 未结 3 1265
甜味超标
甜味超标 2020-12-02 10:59

I have two collections. The first collection contains students:

{ \"_id\" : ObjectId(\"51780f796ec4051a536015cf\"), \"name\" : \"John\" }
{ \"_id\" : Object         


        
相关标签:
3条回答
  • 2020-12-02 11:27

    I am trying to explain by putting problem statement and solution to it. I hope it will help

    Problem Statement:

    Find all the published products, whose name like ABC Product or PQR Product, and price should be less than 15/-

    Solution:

    Below are the conditions that need to be taken care of

    1. Product price should be less than 15
    2. Product name should be either ABC Product or PQR Product
    3. Product should be in published state.

    Below is the statement that applies above criterion to create query and fetch data.

    $elements = $collection->find(
                 Array(
                    [price] => Array( [$lt] => 15 ),
                    [$or] => Array(
                                [0]=>Array(
                                        [product_name]=>Array(
                                           [$in]=>Array(
                                                [0] => ABC Product,
                                                [1]=> PQR Product
                                                )
                                            )
                                        )
                                    ),
                    [state]=>Published
                    )
                );
    
    0 讨论(0)
  • 2020-12-02 11:28

    It seems like the $in operator would serve your purposes just fine.

    You could do something like this (pseudo-query):

    if (db.courses.find({"students" : {"$in" : [studentId]}, "course" : courseId }).count() > 0) {
      // student is enrolled in class
    }
    

    Alternatively, you could remove the "course" : courseId clause and get back a set of all classes the student is enrolled in.

    0 讨论(0)
  • 2020-12-02 11:29

    [edit based on this now being possible in recent versions]

    [Updated Answer] You can query the following way to get back the name of class and the student id only if they are already enrolled.

    db.student.find({},
     {_id:0, name:1, students:{$elemMatch:{$eq:ObjectId("51780f796ec4051a536015cf")}}})
    

    and you will get back what you expected:

    { "name" : "CS 101", "students" : [ ObjectId("51780f796ec4051a536015cf") ] }
    { "name" : "Literature" }
    { "name" : "Physics", "students" : [ ObjectId("51780f796ec4051a536015cf") ] }
    

    [Original Answer] It's not possible to do what you want to do currently. This is unfortunate because you would be able to do this if the student was stored in the array as an object. In fact, I'm a little surprised you are using just ObjectId() as that will always require you to look up the students if you want to display a list of students enrolled in a particular course (look up list of Id's first then look up names in the students collection - two queries instead of one!)

    If you were storing (as an example) an Id and name in the course array like this:

    {
            "_id" : ObjectId("51780fb5c9c41825e3e21fc6"),
            "name" : "Physics",
            "students" : [
                    {id: ObjectId("51780f796ec4051a536015cf"), name: "John"},
                    {id: ObjectId("51780f796ec4051a536015d0"), name: "Sam"}
            ]
    }
    

    Your query then would simply be:

    db.course.find( { }, 
                    { students : 
                        { $elemMatch : 
                           { id : ObjectId("51780f796ec4051a536015d0"), 
                             name : "Sam" 
                           } 
                        } 
                    } 
    );
    

    If that student was only enrolled in CS 101 you'd get back:

    { "name" : "Literature" }
    { "name" : "Physics" }
    {
        "name" : "CS 101",
        "students" : [
            {
                "id" : ObjectId("51780f796ec4051a536015cf"),
                "name" : "John"
            }
        ]
    }
    
    0 讨论(0)
提交回复
热议问题