Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

I have such structure of documents in my products collection:

{
  title: 'Samsung Galaxy S III',
  category_id: ObjectId("50bcc2f0b910a6c1936a4424"),
  properties: [
    {
      title: 'OS',
      value: 'Android'
    },
    {
      title: 'Display',
      value: '4.8"'
    }
  ]
}

Also I've created multikey index: {category_id: 1, 'properties.value': 1, 'properties.title': 1}

What happens when I do query with $all? How it works? Example:

{
  category_id: ObjectId("50bcc2f0b910a6c1936a4424"),
  properties: {
    $all: [
      {
        $elemMatch: {
          title: 'OS',
          value: 'Android'
        }
      },
      {
        $elemMatch: {
          title: 'Display',
          value: '4.8"'
        }
      }
    ]
  }
}

Does it find elements in index by first $elemMatch and then iterate over all found element to ensure second $elemMatch?

For my test collection with 2 androids and 1 ios explain() returns:

{
        "cursor" : "BtreeCursor category_id_1_properties.title_1_properties.value_1",
        "isMultiKey" : true,
        "n" : 1,
        "nscannedObjects" : 2,
        "nscanned" : 2,
        "nscannedObjectsAllPlans" : 2,
        "nscannedAllPlans" : 2,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "indexBounds" : {
            "category_id" : [
                    [
                            ObjectId("50bcc2f0b910a6c1936a4424"),
                            ObjectId("50bcc2f0b910a6c1936a4424")
                    ]
            ],
            "properties.title" : [
                    [
                            "OS",
                            "OS"
                    ]
            ],
            "properties.value" : [
                    [
                            "Android",
                            "Android"
                    ]
            ]
        }
}
share|improve this question
add comment

2 Answers

Yes. But in your case dataset is too small for effective using of index. So MongoDB decided to use full collection scan.

share|improve this answer
    
It use index at least for one $elemMatch. See, I've added "indexBounds". Does it decided to scan all found elements for second $elemMatch? –  Dmitry Dec 7 '12 at 9:07
    
There are a few subquestions in the original post. Could you indicate here which one do you answer? Thanks in advance. –  dezso Dec 7 '12 at 10:02
add comment

First, not sure if you have altered the question or not since posted, but contrary to one of the answers, this is not doing a full collection scan, it is using an index, as evidenced by the "cursor" : "BtreeCursor in the explain output.

As for your question - you are asking about the $all operator, but I think your issue here is that you are using the $elemMatch operator incorrectly. When you do:

$elemMatch: {
          title: 'OS',
          value: 'Android'
        }

Or similar, you are running $elemMatch against a document, not an array, which is how it is intended. Hence the explain shows the bounds on the index as specific values of just OS and Android on properties.title and properties.value respectively rather than what you probably wanted, which I think is to only return if all the various properties are present in the array.

Try without $elemMatch:

{
  category_id: ObjectId("50bcc2f0b910a6c1936a4424"),
  properties: {
    $all: [
      {
          title: 'OS',
          value: 'Android'
      },
      {
          title: 'Display',
          value: '4.8"'
      }
    ]
  }
}
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.