{ "_comment": [ "Inputs only. Expectations are measured -- see record.js.", "`partialFilterExpression`: which filters may be written, what the index", "then reports about itself, and the one behaviour that made ignoring the", "option a wrong answer rather than a missing feature -- a unique partial", "index constrains only the documents its filter selects." ], "documents": [ { "_id": 1, "a": 1, "s": "x" }, { "_id": 2, "a": 5, "s": "y" }, { "_id": 3, "s": "z" }, { "_id": 4, "a": 5, "s": "x" } ], "cases": [ { "description": "a partial index is created and reports its filter", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$gte": 5 } } } }, { "name": "listIndexes", "arguments": {} } ] }, { "description": "a query the filter covers still answers every match", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$gte": 5 } } } }, { "name": "find", "arguments": { "filter": { "a": { "$gte": 5 } }, "sort": { "_id": 1 } } } ] }, { "description": "a query the filter excludes still answers every match", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$gte": 5 } } } }, { "name": "find", "arguments": { "filter": { "a": 1 }, "sort": { "_id": 1 } } } ] }, { "description": "a query straddling the filter still answers every match", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$gte": 5 } } } }, { "name": "find", "arguments": { "filter": { "a": { "$gte": 1 } }, "sort": { "_id": 1 } } }, { "name": "countDocuments", "arguments": { "filter": {} } } ] }, { "description": "a unique partial index accepts duplicates its filter excludes", "documents": [], "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "unique": true, "partialFilterExpression": { "t": true } } }, { "name": "insertMany", "arguments": { "documents": [{ "_id": 1, "a": 1, "t": false }, { "_id": 2, "a": 1, "t": false }] } }, { "name": "find", "arguments": { "filter": {}, "sort": { "_id": 1 } } } ] }, { "description": "a unique partial index refuses duplicates its filter selects", "documents": [], "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "unique": true, "partialFilterExpression": { "t": true } } }, { "name": "insertMany", "arguments": { "documents": [{ "_id": 1, "a": 9, "t": true }, { "_id": 2, "a": 9, "t": true }] } } ] }, { "description": "a document leaving the filter frees the value it held", "documents": [], "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "unique": true, "partialFilterExpression": { "t": true } } }, { "name": "insertMany", "arguments": { "documents": [{ "_id": 1, "a": 9, "t": true }] } }, { "name": "updateOne", "arguments": { "filter": { "_id": 1 }, "update": { "$set": { "t": false } } } }, { "name": "insertOne", "arguments": { "document": { "_id": 2, "a": 9, "t": true } } }, { "name": "find", "arguments": { "filter": {}, "sort": { "_id": 1 } } } ] }, { "description": "a document entering the filter takes the value it names", "documents": [], "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "unique": true, "partialFilterExpression": { "t": true } } }, { "name": "insertMany", "arguments": { "documents": [{ "_id": 1, "a": 9, "t": true }, { "_id": 2, "a": 9, "t": false }] } }, { "name": "updateOne", "arguments": { "filter": { "_id": 2 }, "update": { "$set": { "t": true } } } } ] }, { "_comment": [ "The reads below exist for the implication test: a partial index may", "only answer a query that cannot match a document its filter left", "out. Each pairs a query that implies the filter with one that does", "not and touches the same field, so an implication test that says yes", "too readily loses the documents outside the filter -- which is a", "wrong answer a result comparison can see, unlike the index being", "used at all, which no client can observe." ], "description": "a query that leaves the filter's field out still sees past it", "documents": [ { "_id": 1, "a": 1, "t": true }, { "_id": 2, "a": 1, "t": false }, { "_id": 3, "a": 2, "t": true } ], "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "t": true } } }, { "name": "find", "arguments": { "filter": { "a": 1 }, "sort": { "_id": 1 } } }, { "name": "find", "arguments": { "filter": { "a": 1, "t": true }, "sort": { "_id": 1 } } }, { "name": "find", "arguments": { "filter": { "a": 1, "t": false }, "sort": { "_id": 1 } } } ] }, { "description": "an $in straddling the filter still answers every match", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$gte": 5 } } } }, { "name": "find", "arguments": { "filter": { "a": { "$in": [1, 5] } }, "sort": { "_id": 1 } } }, { "name": "find", "arguments": { "filter": { "a": { "$in": [5, 9] } }, "sort": { "_id": 1 } } } ] }, { "description": "a query for null does not belong to an index that requires the field", "documents": [ { "_id": 1, "a": 1 }, { "_id": 2 }, { "_id": 3, "a": null } ], "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$exists": true } } } }, { "name": "find", "arguments": { "filter": { "a": null }, "sort": { "_id": 1 } } }, { "name": "find", "arguments": { "filter": { "a": 1 }, "sort": { "_id": 1 } } } ] }, { "description": "an equality inside the filter's range, and one outside it", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$gt": 3 } } } }, { "name": "find", "arguments": { "filter": { "a": 5 }, "sort": { "_id": 1 } } }, { "name": "find", "arguments": { "filter": { "a": 1 }, "sort": { "_id": 1 } } }, { "name": "find", "arguments": { "filter": { "a": { "$gt": 4 } }, "sort": { "_id": 1 } } }, { "name": "find", "arguments": { "filter": { "a": { "$gt": 0 } }, "sort": { "_id": 1 } } } ] }, { "description": "a sort a partial index could serve", "documents": [ { "_id": 1, "a": 3, "t": true }, { "_id": 2, "a": 1, "t": false }, { "_id": 3, "a": 2, "t": true } ], "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "t": true } } }, { "name": "find", "arguments": { "filter": { "t": true }, "sort": { "a": 1 } } }, { "name": "find", "arguments": { "filter": {}, "sort": { "a": 1 } } } ] }, { "description": "a unique partial index answers the read it constrains", "documents": [ { "_id": 1, "a": 9, "t": true }, { "_id": 2, "a": 9, "t": false } ], "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "unique": true, "partialFilterExpression": { "t": true } } }, { "name": "find", "arguments": { "filter": { "a": 9, "t": true }, "sort": { "_id": 1 } } }, { "name": "find", "arguments": { "filter": { "a": 9 }, "sort": { "_id": 1 } } } ] }, { "description": "a filter on $exists", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$exists": true } } } }, { "name": "listIndexes", "arguments": {} } ] }, { "description": "a filter with two predicates", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$gt": 0 }, "s": "x" } } }, { "name": "listIndexes", "arguments": {} } ] }, { "description": "a filter with an explicit $and", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "$and": [{ "a": { "$gt": 0 } }] } } }, { "name": "listIndexes", "arguments": {} } ] }, { "description": "a filter on a field the index does not name", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "s": "x" } } }, { "name": "listIndexes", "arguments": {} } ] }, { "description": "a filter using $regex is refused", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "s": { "$regex": "x" } } } } ] }, { "description": "a filter using $ne is refused", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$ne": 1 } } } } ] }, { "description": "a filter using $in is refused", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$in": [1, 2] } } } } ] }, { "description": "a filter that is not a document is refused", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": 1 } } ] }, { "description": "an empty filter", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": {} } }, { "name": "listIndexes", "arguments": {} } ] }, { "description": "sparse and a partial filter may not be combined", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "sparse": true, "partialFilterExpression": { "a": { "$gt": 0 } } } } ] }, { "description": "a partial filter with a TTL", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "expireAfterSeconds": 100, "partialFilterExpression": { "a": { "$gt": 0 } } } }, { "name": "listIndexes", "arguments": {} } ] }, { "description": "a partial index on a compound key", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1, "s": 1 }, "partialFilterExpression": { "a": { "$gt": 0 } } } }, { "name": "listIndexes", "arguments": {} } ] }, { "description": "two indexes on one key differing only in their filter", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "name": "one", "partialFilterExpression": { "a": { "$gt": 0 } } } }, { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "name": "two", "partialFilterExpression": { "a": { "$gt": 4 } } } }, { "name": "listIndexes", "arguments": {} } ] }, { "description": "the same index twice is idempotent", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$gt": 0 } } } }, { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$gt": 0 } } } }, { "name": "listIndexes", "arguments": {} } ] }, { "description": "the same name with a different filter conflicts", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$gt": 0 } } } }, { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "partialFilterExpression": { "a": { "$gt": 4 } } } } ] }, { "description": "a partial index is dropped by name", "ops": [ { "name": "createIndex", "arguments": { "keys": { "a": 1 }, "name": "pa", "partialFilterExpression": { "a": { "$gt": 0 } } } }, { "name": "dropIndex", "arguments": { "name": "pa" } }, { "name": "listIndexes", "arguments": {} } ] } ] }