MongoDB TTL sparse index? - mongodb

Can you TTL a sparse field? If so, should you declare the TTL index sparse? Like so?
db.eventlog.createIndex( { "lastModifiedDate": 1 }, { expireAfterSeconds: 3600 , sparse:"true"} )

> use foo
switched to db foo
> db.foo.createIndex({date: 1}, {expireAfterSeconds: 5, sparse: true})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.foo.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "foo.foo"
},
{
"v" : 1,
"key" : {
"date" : 1
},
"name" : "date_1",
"ns" : "foo.foo",
"expireAfterSeconds" : 5,
"sparse" : true
}
]
> db.foo.insert({date: new Date()})
> db.foo.find()
{ "_id" : ObjectId("5841aeb650b5412e92ebbb9b"), "date" : ISODate("2016-12-02T17:26:14.617Z") }
> db.foo.find()
>
It appears that this worked fine. Note that according to the documentation , the TTL operation fires every 60 seconds or so, so the expireAfterSeconds: 5 may take longer.

Related

mongodb - indexes disappear after few minutes

Have tested this on MongoDB 3.4 and 3.6:
Create one or more indexes in a collection
rs1:PRIMARY> db.coll.createIndex({checkinDate:1}, {background:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1,
"operationTime" : Timestamp(1518162276, 2),
"$clusterTime" : {
"clusterTime" : Timestamp(1518162276, 2),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
Now list the indexes.
rs1:PRIMARY> db.coll.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "cico.coll"
},
{
"v" : 2,
"key" : {
"checkinDate" : 1
},
"name" : "checkinDate_1",
"ns" : "cico.coll",
"background" : 1
}
]
Wait for some time (few mins)
List the indexes again:
rs1:PRIMARY> db.coll.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "cico.coll"
}
]
I have no clue why these indexes created are getting deleted? Any help appreciated.
Index option background is of type boolean, try:
db.coll.createIndex (
{ checkinDate:1 }, { background: true }
)
this is actually a non-issue. there was a program, running in the background, which was dropping all the indexes periodically (for a completely different reason).

Mongo Case Insensitive index (collation) not getting results

I'm trying to use the CaseInsensitive Index using Mongoid 5. I even went down to the Mongo console to run the experiments but it won't pull the results at all:
> db.charges.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "paymentsapi_development.charges"
}
]
> db.charges.createIndex({'details.email':1},{name:'emails_index',collation:{locale:'en',strength:1}})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.charges.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "paymentsapi_development.charges"
},
{
"v" : 1,
"key" : {
"details.email" : 1
},
"name" : "emails_index",
"ns" : "paymentsapi_development.charges",
"collation" : {
"locale" : "en",
"strength" : 1
}
}
]
> db.charges.find({'details.email':'lolo#lolo.com'}).count()
1
> db.charges.find({'details.email':'LoLo#LoLo.cOm'}).collation({locale:'en',strength:1}).count()
0
>
I'm basing in the Collation (https://docs.mongodb.com/manual/reference/collation/) and the Case Insensitive Index (https://docs.mongodb.com/manual/core/index-case-insensitive/) .
I already checked the db version, the db.adminCommand( { setFeatureCompatibilityVersion: <version> } ) based on https://docs.mongodb.com/manual/reference/command/setFeatureCompatibilityVersion/ and all further things possible.
Any help is very appreciated.

When renaming a MongoDB collection, are the indices intact?

When performing this operation, will indices remain intact?
db.collection('my-collection').rename('new-collection-name', {dropTarget:true});
Using the mongo cli, it's easy to test:
$ mongo
> db.bob.ensureIndex({ name: 1 })
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.bob.renameCollection('robert', { dropTarget: true })
{ "ok" : 1 }
> db.robert.getIndices()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.robert"
},
{
"v" : 1,
"key" : {
"name" : 1
},
"name" : "name_1",
"ns" : "test.robert"
}
]
So, yes, it looks like the indices do remain intact.

Documents not expiring using TTL in mongodb 2.6.7

I'm trying the TTL feature in a mongo shell but I cannot seem to make it work. I have triple check everything using the documentation.
Here is what I did:
MongoDB shell version: 2.6.7
connecting to: test
> db.streamers.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.streamers"
},
{
"v" : 1,
"key" : {
"room" : 1
},
"name" : "room_1",
"ns" : "test.streamers",
"background" : true,
"safe" : null
},
{
"v" : 1,
"key" : {
"lastAlive" : 1
},
"name" : "lastAlive_1",
"ns" : "test.streamers",
"expiresAfterSeconds" : 60,
"background" : true,
"safe" : null
}
]
> db.streamers.insert({ _id: "hello", room: "yop", lastAlive: new Date() })
WriteResult({ "nInserted" : 1 })
[waiting for a while here...]
> db.streamers.find({ _id: "hello" })
{ "_id" : "hello", "room" : "yop", "lastAlive" : ISODate("2015-02-18T13:03:02.836Z") }
> new Date()
ISODate("2015-02-18T13:50:50.403Z")
So clearly, the document is not being removed even after waiting for more than an hour. db.currentOp() returns an empty array as well.
This is a dev environment so mongodb is in a standalone configuration with default settings. A getParameter on ttlMonitorEnabled returns true so that's fine too.
What is wrong here ?
There was a typo in your index creation.
The setting expiresAfterSeconds should be expireAfterSeconds.

Cannot create a TTL index on a field that already has an index. ...really?

From the 10Gen Docs:
"You cannot create a TTL index on a field that already has an index."
However, it seems like this works just fine. What do the docs really mean?
In this example I create multiple indexes on field d before adding TTL. TTL appears correct:
"expireAfterSeconds" : 5
and the documents are removed correctly.
mongo shell:
> db.boo.ensureIndex({a: 1, b: 1, d: -1})
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.boo.ensureIndex({d: -1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 2,
"numIndexesAfter" : 3,
"ok" : 1
}
> db.boo.ensureIndex({d: 1}, {expireAfterSeconds: 5});
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 3,
"numIndexesAfter" : 4,
"ok" : 1
}
> db.boo.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.boo"
},
{
"v" : 1,
"key" : {
"a" : 1,
"b" : 1,
"d" : -1
},
"name" : "a_1_b_1_d_-1",
"ns" : "test.boo"
},
{
"v" : 1,
"key" : {
"d" : -1
},
"name" : "d_-1",
"ns" : "test.boo"
},
{
"v" : 1,
"key" : {
"d" : 1
},
"name" : "d_1",
"ns" : "test.boo",
"expireAfterSeconds" : 5
}
]
Edit/Summary:
The combination that is actually restricted is adding a TTL expiration to an existing index, like this:
> db.boo.ensureIndex({d: 1});
{
"createdCollectionAutomatically" : true,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
> db.boo.ensureIndex({d: 1}, {expireAfterSeconds: 5});
{
"ok" : 0,
"errmsg" : "Index with name: d_1 already exists with different options",
"code" : 85
}
You have actually created different index type (descending).
Commands:
db.boo.ensureIndex({d: -1})
and
db.boo.ensureIndex({d: 1})
will create two separate indexes (although on the same field).
If you try to create a descending TTL index:
db.boo.ensureIndex({d: -1}, {expireAfterSeconds: 5})
you will get an error:
Index with name ... already exists with different options
If you try to be "clever" and change the name of the index you will get:
Index with pattern... already exists with different options
I guess you should submit a bug to describe that more precisely in their documentation / tutorial.