Dynamically Create Index with Mongoid

Dynamically create index with mongoid

Saying Model.index(:field => -1), more or less, just registers the existence of the index with Model, it doesn't actually create an index. You're looking for create_indexes:

- (true) create_indexes

Send the actual index creation comments to the MongoDB driver

So you'd want to say:

Model.index(field: -1)
Model.create_indexes

You can also create them directly through Moped by calling create on the collection's indexes:

Mongoid::Sessions.default[:models].indexes.create(field: -1)
Model.collection.indexes.create(field: 1)
# or in newer versions:
Model.collection.indexes.create_one(field: 1)

Mongoid::Sessions has been renamed to Mongoid::Clients in newer versions so you might need to say:

Mongoid::Clients.default[:models].indexes.create(field: 1)
Model.collection.indexes.create(field: 1)
# or in even newer versions:
Model.collection.indexes.create_one(field: 1)

Thanks to js_ and mltsy for noting these changes.

How to create text index in mongoid 5?

I found the solution

index({company_name: 'text', first_name: 'text', last_name: 'text' })

You just have to pass 'text' instead of 1.

mongoid create text index on all text fields on model

You can create the index you need as the second line in the following example:

client = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'music') 
client[:bands].indexes.create_one( { "$**": "text" } )

Take a look to this link for further information:
https://github.com/mongodb/mongo-ruby-driver/blob/master/docs/tutorials/ruby-driver-indexing.txt

Does build createIndex() a new index over the whole collection?

Building an index indexes all existing documents and also cause all future documents to get indexed as well. So if you insert new documents into an already indexed collection (or update the indexed fields of existing documents), the indexes will get updated.

When you call createIndex and an index of the same type over the same fields already exists, nothing happens.

MongoDb get record based on dynamic keys

The following aggregation pipeline would be able to achieve what you're looking for, note however that this isn't a very mongo-friendly data format. https://mongoplayground.net/p/ZRcbzEe1bkR

db.collection.aggregate([
{
$project: {
CustomerID: 1,
entries: {
$objectToArray: "$$ROOT"
}
}
},
{
$unwind: "$entries"
},
{
$unwind: "$entries.v"
},
{
$match: {
"entries.v.source": "SourceX"
}
},
{
$project: {
_id: 0,
CustomerID: 1,
code: "$entries.v.code"
}
}
])

If you are able to, I strongly suggest you change your data to just have a single array, in which case you can easily utilize indexes to speed up queries. The following setup could utilize an index on codes.source to heavily speed up the initial match. https://mongoplayground.net/p/hBC1F-g9af1

{
"_id": ObjectId("5f0339e28fbb15b9f8a17181"),
"CustomerID": "12345",
"codes": [
{
"datetime": ISODate("2020-06-13"),
"source": "SourceX",
"code": "ABC"
},
{
"datetime": ISODate("2020-08-18"),
"source": "SourceB",
"code": "ABC"
},
{
"datetime": ISODate("2020-02-16"),
"source": "SourceX",
"code": "WQA"
},
{
"datetime": ISODate("2020-03-16"),
"source": "SourceY",
"code": "WQA"
}
]
}

And then you could use a slightly modified aggregation pipeline to achieve the result you want.

db.collection.aggregate([
{
$match: {
"codes.source": "SourceX"
}
},
{
$unwind: "$codes"
},
{
$match: {
"codes.source": "SourceX"
}
},
{
$project: {
_id: 0,
CustomerID: 1,
code: "$codes.code"
}
}
])


Related Topics



Leave a reply



Submit