-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathmongoIndex.js
More file actions
140 lines (131 loc) · 4.18 KB
/
mongoIndex.js
File metadata and controls
140 lines (131 loc) · 4.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
/**
* This class represents an index in a collection.
* @param collection - collection name
* @param cols - array of column names
* @param orders - array of orders in the same position of cols
* @param flippableOrders - index positions which can be flipped from 1 to -1 or vice versa
* @param options - object of options for the createIndex function
*/
var Index = function(collection, cols, orders, flippableOrders, options) {
if (!collection || !cols || !orders) {
throw "empty collection, orders or columns";
}
if (cols.length !== orders.length) {
throw "cols and orders lengths do not match";
}
flippableOrders.forEach(function(x) {
if (x >= cols.length) {
throw "column position is out of bounds";
}
});
this.collection = collection;
this.cols = cols;
this.orders = orders;
this.flippableOrders = flippableOrders;
this.options = options || {};
};
/**
* Builds the createIndex command from this Index object
* @returns {String} the full command
*/
Index.prototype.buildIndexCommand = function() {
const queryPostfix = ")";
var queryPrefix = "db." + this.collection + ".createIndex(";
var indexes = "{";
var indexPrefix = "";
for (var i=0; i<this.cols.length; i++) {
indexes += indexPrefix + "'" + this.cols[i] + "'" + ": " + this.orders[i];
indexPrefix = ", ";
}
indexes += "}";
return queryPrefix + indexes + ", " + JSON.stringify(this.options) + queryPostfix;
};
/**
* Checks if the index given is a reverse of this index
* Index Predicate
* @param index - the index to check against this
* @returns true iff the index given is a reverse of this one
*/
Index.prototype.isReverse = function(index) {
if (this.collection !== index.collection) {
return false;
}
for (var i=0; i<this.cols.length; i++) {
if (this.cols[i] !== index.cols[i] || this.orders[i] * index.orders[i] !== -1) {
return false;
}
}
return true;
};
/**
* Checks if the given index is a prefix of this Index (including full prefix, i.e: full equality)
* Index Predicate
* @param index - the index to check against this
* @returns true iff the index given is a prefix of this Index
*/
Index.prototype.isPrefix = function(index) {
if (this.collection !== index.collection || index.cols.length > this.cols.length) {
return false;
}
for (var i=0; i<index.cols.length; i++) {
if (this.cols[i] !== index.cols[i] || this.orders[i] !== index.orders[i]) {
return false;
}
}
return true;
};
/**
* Checks if the given index is identical in columns, ignoring the index directions (-1 / 1)
* @param index index to check against this
* @return true iff the index given is identical in columns
*/
Index.prototype.isFlippable = function(index) {
if (this.collection !== index.collection || index.cols.length !== this.cols.length) {
return false;
}
for (var i=0; i<index.cols.length; i++) {
if (this.cols[i] !== index.cols[i] || index.flippableOrders.indexOf(i) < 0) {
return false;
}
}
return true;
}
/**
* Flips the orders in given positions
* This allows for changing the index for bits that don't matter.
* @param true iff the operation succeeded
*/
Index.prototype.flipOrders = function(positions) {
for (var p in positions) {
var pos = positions[p];
if (this.flippableOrders.indexOf(pos) < 0) {
return false;
}
this.orders[pos] *= -1;
}
return true;
}
/**
* Checks if this index is already satisfied by the given index
* Index Predicate
* @param index - index to check if covers this Index
* @returns true iff the given index covers this index
*/
Index.prototype.isCovered = function(index) {
return index.isPrefix(this);
};
/**
* Lazy way to implement equals.
* @param Index Predicate
*/
Index.prototype.equals = function(index) {
return this.isPrefix(index) && index.isPrefix(this);
};
/**
* Setter for options.
* The allows setting index options just before running the buildIndexCommand function.
*/
Index.prototype.setOptions = function(options) {
this.options = options;
}
module.exports = Index;