@@ -673,57 +673,52 @@ private IMongoQuery BuildNotQuery(UnaryExpression unaryExpression)
673673 if ( queryDocument . ElementCount == 1 )
674674 {
675675 var elementName = queryDocument . GetElement ( 0 ) . Name ;
676- if ( elementName == "$or" )
676+ switch ( elementName )
677677 {
678- var clauses = queryDocument [ 0 ] . AsBsonArray ;
679- return new QueryDocument ( "$nor" , clauses ) ;
678+ case "$and" :
679+ // there is no $nand and $not only works as a meta operator on a single operator so simulate $not using $nor
680+ return new QueryDocument ( "$nor" , new BsonArray { queryDocument } ) ;
681+ case "$or" :
682+ return new QueryDocument ( "$nor" , queryDocument [ 0 ] . AsBsonArray ) ;
683+ case "$nor" :
684+ return new QueryDocument ( "$or" , queryDocument [ 0 ] . AsBsonArray ) ;
680685 }
681686
682687 var operatorDocument = queryDocument [ 0 ] as BsonDocument ;
683- if ( operatorDocument != null && operatorDocument . ElementCount == 1 )
688+ if ( operatorDocument != null && operatorDocument . ElementCount > 0 )
684689 {
685690 var operatorName = operatorDocument . GetElement ( 0 ) . Name ;
686- switch ( operatorName )
691+ if ( operatorDocument . ElementCount == 1 )
687692 {
688- case "$exists" :
689- var boolValue = operatorDocument [ 0 ] . AsBoolean ;
690- return new QueryDocument ( elementName , new BsonDocument ( "$exists" , ! boolValue ) ) ;
691- case "$in" :
692- var values = operatorDocument [ 0 ] . AsBsonArray ;
693- return new QueryDocument ( elementName , new BsonDocument ( "$nin" , values ) ) ;
694- case "$not" :
695- var predicate = operatorDocument [ 0 ] ;
696- return new QueryDocument ( elementName , predicate ) ;
697- case "$lt" :
698- case "$lte" :
699- case "$ne" :
700- case "$gt" :
701- case "$gte" :
702- string oppositeOperator ;
703- switch ( operatorName )
704- {
705- case "$lt" : oppositeOperator = "$gte" ; break ;
706- case "$lte" : oppositeOperator = "$gt" ; break ;
707- case "$ne" : oppositeOperator = "$eq" ; break ;
708- case "$gt" : oppositeOperator = "$lte" ; break ;
709- case "$gte" : oppositeOperator = "$lt" ; break ;
710- default : throw new InvalidOperationException ( "Unreachable code." ) ;
711- }
712- var comparisonValue = operatorDocument [ 0 ] ;
713- if ( oppositeOperator == "$eq" )
714- {
693+ switch ( operatorName )
694+ {
695+ case "$exists" :
696+ var boolValue = operatorDocument [ 0 ] . AsBoolean ;
697+ return new QueryDocument ( elementName , new BsonDocument ( "$exists" , ! boolValue ) ) ;
698+ case "$in" :
699+ var values = operatorDocument [ 0 ] . AsBsonArray ;
700+ return new QueryDocument ( elementName , new BsonDocument ( "$nin" , values ) ) ;
701+ case "$not" :
702+ var predicate = operatorDocument [ 0 ] ;
703+ return new QueryDocument ( elementName , predicate ) ;
704+ case "$ne" :
705+ var comparisonValue = operatorDocument [ 0 ] ;
715706 return new QueryDocument ( elementName , comparisonValue ) ;
716- }
717- else
718- {
719- return new QueryDocument ( elementName , new BsonDocument ( oppositeOperator , comparisonValue ) ) ;
720- }
707+ }
708+ if ( operatorName [ 0 ] == '$' )
709+ {
710+ // use $not as a meta operator on a single operator
711+ return new QueryDocument ( elementName , new BsonDocument ( "$not" , operatorDocument ) ) ;
712+ }
721713 }
722-
723- // use $not as a meta operator
724- if ( operatorName [ 0 ] == '$' )
714+ else
725715 {
726- return new QueryDocument ( elementName , new BsonDocument ( "$not" , operatorDocument ) ) ;
716+ // $ref isn't an operator (it's the first field of a DBRef)
717+ if ( operatorName [ 0 ] == '$' && operatorName != "$ref" )
718+ {
719+ // $not only works as a meta operator on a single operator so simulate $not using $nor
720+ return new QueryDocument ( "$nor" , new BsonArray { queryDocument } ) ;
721+ }
727722 }
728723 }
729724
@@ -733,20 +728,11 @@ private IMongoQuery BuildNotQuery(UnaryExpression unaryExpression)
733728 return new QueryDocument ( elementName , new BsonDocument ( "$not" , operatorValue ) ) ;
734729 }
735730
736- if ( operatorValue . IsBoolean )
737- {
738- // turn implied boolean test into test against opposite boolean value
739- var oppositeValue = ! operatorValue . AsBoolean ;
740- return new QueryDocument ( elementName , oppositeValue ) ;
741- }
742- else
743- {
744- // turn implied equality comparison into $ne
745- return new QueryDocument ( elementName , new BsonDocument ( "$ne" , operatorValue ) ) ;
746- }
731+ // turn implied equality comparison into $ne
732+ return new QueryDocument ( elementName , new BsonDocument ( "$ne" , operatorValue ) ) ;
747733 }
748734
749- // $not only works as a meta operator so simulate $not using $nor
735+ // $not only works as a meta operator on a single operator so simulate $not using $nor
750736 return new QueryDocument ( "$nor" , new BsonArray { queryDocument } ) ;
751737 }
752738
0 commit comments