@@ -481,6 +481,59 @@ def test_create():
481481 # Index wasn't created, only the default index on _id
482482 self .assertEqual (1 , len (db .test .index_information ()))
483483
484+ @client_context .require_version_min (3 , 1 , 9 , - 1 )
485+ def test_index_filter (self ):
486+ db = self .db
487+ db .drop_collection ("test" )
488+
489+ # Test bad filter spec on create.
490+ self .assertRaises (OperationFailure , db .test .create_index , "x" ,
491+ partialFilterExpression = 5 )
492+ self .assertRaises (OperationFailure , db .test .create_index , "x" ,
493+ partialFilterExpression = {"x" : {"$asdasd" : 3 }})
494+ self .assertRaises (OperationFailure , db .test .create_index , "x" ,
495+ partialFilterExpression = {"$and" : 5 })
496+ self .assertRaises (OperationFailure , db .test .create_index , "x" ,
497+ partialFilterExpression = {
498+ "$and" : [{"$and" : [{"x" : {"$lt" : 2 }},
499+ {"x" : {"$gt" : 0 }}]},
500+ {"x" : {"$exists" : True }}]})
501+
502+ self .assertEqual ("x_1" , db .test .create_index (
503+ [('x' , ASCENDING )], partialFilterExpression = {"a" : {"$lte" : 1.5 }}))
504+ db .test .insert_one ({"x" : 5 , "a" : 2 })
505+ db .test .insert_one ({"x" : 6 , "a" : 1 })
506+
507+ # Operations that use the partial index.
508+ explain = db .test .find (
509+ {"x" : 6 , "a" : 1 }).explain ()['queryPlanner' ]['winningPlan' ]
510+ self .assertEqual ("x_1" , explain .get ('inputStage' , {}).get ('indexName' ))
511+ self .assertTrue (explain .get ('inputStage' , {}).get ('isPartial' ))
512+ explain = db .test .find (
513+ {"x" : {"$gt" : 1 }, "a" : 1 }).explain ()['queryPlanner' ]['winningPlan' ]
514+ self .assertEqual ("x_1" , explain .get ('inputStage' , {}).get ('indexName' ))
515+ self .assertTrue (explain .get ('inputStage' , {}).get ('isPartial' ))
516+ explain = db .test .find (
517+ {"x" : 6 ,
518+ "a" : {"$lte" : 1 }}).explain ()['queryPlanner' ]['winningPlan' ]
519+ self .assertEqual ("x_1" , explain .get ('inputStage' , {}).get ('indexName' ))
520+ self .assertTrue (explain .get ('inputStage' , {}).get ('isPartial' ))
521+
522+ # Operations that do not use the partial index.
523+ explain = db .test .find (
524+ {"x" : 6 ,
525+ "a" : {"$lte" : 1.6 }}).explain ()['queryPlanner' ]['winningPlan' ]
526+ self .assertEqual ("COLLSCAN" , explain .get ('stage' ))
527+ explain = db .test .find (
528+ {"x" : 6 }).explain ()['queryPlanner' ]['winningPlan' ]
529+ self .assertEqual ("COLLSCAN" , explain .get ('stage' ))
530+
531+ # Test drop_indexes.
532+ db .test .drop_index ("x_1" )
533+ explain = db .test .find (
534+ {"x" : 6 , "a" : 1 }).explain ()['queryPlanner' ]['winningPlan' ]
535+ self .assertEqual ("COLLSCAN" , explain .get ('stage' ))
536+
484537 def test_field_selection (self ):
485538 db = self .db
486539 db .drop_collection ("test" )
0 commit comments