-
Notifications
You must be signed in to change notification settings - Fork 2
Indices
Indices in KiwiDB are designed to flexible and easy to use in real world scenarios without big surprises.
KIWIDB HAS STOLEN THE WHOLE CONCEPT OF INDICES FROM MONGODB.
So, I said it. And perhaps it will also give you a sense of familiarity.
But beware. MongoDB is quite smart since it can use all sort of predicate (less than, bigger than etc), whereas KiwiDB only understands one:
- equality of values
Luckily, as we will see, the meaning of equality can be configured...
Lets say you have an object model like this:
public class User {
public string Name {get; set;}
public Ticket[] Tickets {get; set;}
]
public class Ticket{
bool IsOpen{ get; set; }
string Category {get; set; }
string Text {get; set; }
}The operation of finding all users with open tickets can be written like
var collection = new Collection("tickets.db")
var filter = new {Tickets = new {IsOpen = true}};
var usersWithOpenTickets = collection.Find<User>(filter);Pay attention to the filter object. It encapsulates exactly the parts of User that we are interested in. In fact, Find() matches objects using at least equal to.
We can speed up the operation by creating an index.
var collection = new Collection("tickets.db")
collection.Indices.EnsureIndex("Tickets.IsOpen")The index name "Tickets.IsOpen" is the JPath (Javascript object member path) to the member to index.
We dont have to specify any datatypes, since an index in practice happily indexes whatever you give it.
Its possible to create a unique index to enforce that not more than one object may have that particular value.
collection.Indices.EnsureIndex(<Path to member>, new IndexOptions(){ IsUnique = true });Inserting an object violating the uniqueness of the index will throw a DuplicateKeyException.
In the case an indexed value is a string, it can be handled inoring case.
collection.Indices.EnsureIndex(<Path to member>, new IndexOptions(){ WhenStringThenIgnoreCase = true });Normally, dates are compared using the full (year,month,day,hour,second,millisecond) value, but in the case when only the day matters, use
collection.Indices.EnsureIndex(<Path to member>, new IndexOptions(){ WhenDateThenIgnoreTimeOfDay = true });After serializing an object to Json, the index values are extacted and depending on type they are handled differently:
Simple types ar indexed by exact value. The simple types are those directly convertible to
- booleans (System.Boolean)
- integers (System.Int32),
- strings (System.String)
- dates (System.DateTime)
- floating point numbers (System.Double)
Arrays, lists or other enumerables are indexed by indexing each separate member.
Complex types are not indexed, even though objects are perfectly valid Json values.
Null values are indexed so you can search for them.
var collection = new Collection("tickets.db")
collection.Find(new {Tickets = null});Preferably at application startup. EnsureIndex will do nothing if an index with the same name and options exists, but its still not a completely free operation.
EnsureIndex fails with a DuplicateKeyException if you upgrade and index to unique and values are not distinct.
EnsureIndex is currently slightly bugged, since it can't detect a change of index semantics, and thus might leave an old, bad index intact as long as the names match.
Yup, use DropIndex.
collection.Indices.DropIndex("Tickets.IsOpen")