1

I have this subdocument embedded in an array:

 company:{
    products:[
      { vehicle: "Toyota", Model: "Camry" },
      { vehicle: "Honda", Model: "Civic" },
      { vehicle: "Honda", Model: "Accord" },
      { vehicle: "Mercedes", Model: "vboot" },
    ]
 }

How do I select the vehicle that matches only

{vehicle:'Honda', Model:'Civic'}

Thus:

company:{
    products:[         
      { vehicle: "Honda", Model: "Civic" },
    ]
 }
1
  • You need to use $elemMatch, why vehicle array has no key? Commented Feb 5, 2018 at 7:08

2 Answers 2

2

Given a document like this:

{
    "_id" : ....,
    "company" : [ 
        {
            "vehicle" : "Toyota",
            "Model" : "Camry"
        }, 
        {
            "vehicle" : "Honda",
            "Model" : "Civic"
        }, 
        {
            "vehicle" : "Honda",
            "Model" : "Accord"
        }, 
        {
            "vehicle" : "Mercedes",
            "Model" : "vboot"
        }
    ]
}

The following query uses the $elemMatch query operator to find only those documents having vehicle:'Honda' and Model:'Civic':

db.collection.find(
    { company: { $elemMatch: { vehicle: 'Honda', Model: 'Civic' } } }
)

If you only want to return the first element in the company array having vehicle:'Honda' and Model:'Civic' then you should use the $elemMatch projection operator:

db.collection.find(
    // only find documents which have a company entry having vehicle=Honda and model=Civic
    { company: { $elemMatch: { vehicle: 'Honda', Model: 'Civic' } } }, 

    // for the documents found by the previous clause, only return the first element
    // in the company array which has vehicle=Honda and model=Civic
    { company: { $elemMatch: { vehicle: 'Honda', Model: 'Civic' } } }
)

// returns:

{
    "_id" : ObjectId("5a79613f85c9cec3a82c902c"),
    "company" : [ 
        {
            "vehicle" : "Honda",
            "Model" : "Civic"
        }
    ]
}

From the docs:

The $elemMatch operator matches documents that contain an array field with at least one element that matches all the specified query criteria.

The $elemMatch operator limits the contents of an <array> field from the query results to contain only the first element matching the $elemMatch condition.

Sign up to request clarification or add additional context in comments.

3 Comments

thanks glyching for your reply but i use $elemMatch it select both vehicle with model 'Civic and Accord' instead of just 'Civic' as i wish
It sounds like you actually want to $elemMatch on the $project. Can you please update your answer with an example document showing exactly what response you want your query to return. Without that anyone attempting to answer this question has to guess what your requirements are.
@yaxx I have updated the answer to include usage of the $elemMatch projection operator.
0

The find() keyword needs to be used for the specific element:

db.company.find({vehicle:"Honda",Model:"Civic"})

1 Comment

that did not work because the object is nested within an array

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.