user1130176
user1130176

Reputation: 1878

mongoid index still resulting in a COLLSCAN

I have a simple class with a simple index

class A
    include Mongoid::Document

    field :value
    index({value: 1})

at the command line, I reindex

bundle exec rake db:mongoid:remove_indexes
bundle exec rake db:mongoid:create_indexes

But when I run a simple query in the rails console

A.where(value: "1").to_a

The mongodb log clearly shows a COLLSCAN

command test_development.a command: find { find: "a", filter: { value: "1" }, 
$db: "test_development", lsid: { id: UUID("fa470127-398a-4f06-9a17-57b058017cf7") } }   
planSummary: COLLSCAN keysExamined:0 docsExamined:816688 cursorExhausted:1 
numYields:6380 nreturned:0 

What am I doing wrong?

update - added additional information:

db.case_data.getIndexSpecs()
[
    {
            "v" : 2,
            "key" : {
                    "_id" : 1
            },
            "name" : "_id_",
            "ns" : "simple_development.case_data"
    },
    {
            "v" : 2,
            "key" : {
                    "_fts" : "text",
                    "_ftsx" : 1
            },
            "name" : "value_text",
            "ns" : "simple_development.case_data",
            "weights" : {
                    "value" : 1
            },
            "default_language" : "english",
            "language_override" : "language",
            "textIndexVersion" : 3
    }
]

output of explain:

db.case_data.find({value: "test"}).explain()
{
    "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "simple_development.case_data",
            "indexFilterSet" : false,
            "parsedQuery" : {
                    "value" : {
                            "$eq" : "test"
                    }
            },
            "queryHash" : "7E4E9C25",
            "planCacheKey" : "7E4E9C25",
            "winningPlan" : {
                    "stage" : "COLLSCAN",
                    "filter" : {
                            "value" : {
                                    "$eq" : "test"
                            }
                    },
                    "direction" : "forward"
            },
            "rejectedPlans" : [ ]
    },
    "serverInfo" : {
            "host" : "msc-2",
            "port" : 27017,
            "version" : "4.2.8",
            "gitVersion" : "43d25964249164d76d5e04dd6cf38f6111e21f5f"
    },
    "ok" : 1
}

Upvotes: 0

Views: 399

Answers (2)

user1130176
user1130176

Reputation: 1878

In some combination of Mongoid 7.1.1 and mongodb 4.2.9, the rake task and the mongorestore both do not actually recreate indexes. They say they do, but they do not.

This command results in COLLSCANs:

bundle exec rake db:mongoid:remove_indexes
bundle exec rake db:mongoid:create_indexes

Using either mongo console to make index, or in each model, in a Rails console, doing:

A.remove_indexes
A.create_indexes

results in no COLLSCANs.

I've repeated this scientifically with clean db restores, and can say with certainty that the rake command and the mongorestore command do not recreate indexes. My solution above fixes the issue.

Thanks to everyone for your help, Kevin

Upvotes: 1

Udi Cohen
Udi Cohen

Reputation: 1289

I don't know why the index was created like that, maybe it is because you didn't specify the field's type in the model class. Try to specify the type of the field, then manually drop the index in mongo shell db.getCollection('X').dropIndex('value_text'), and then run the rake for creating indices rake db:create_indexes.

If that doesn't work I would drop the index and manually create one in mongo shell db.getCollection('X').createIndex({'value': 1}, {name: 'value_1', background: true}) (or wait for a better answer 😉 )

Upvotes: 0

Related Questions