fdZddlZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl Z ddl Z ddlZddlZddlZddlmZddlZddlmZddlmZddlmZddlmZ dd lmZdd lmZmZd Zej<efZe jBZ"gd Z#hdZ$hdZ%e$e%zddhzZ&gdZ'dgZ(ddgZ)gdZ*ddgZ+gdZ,dgZ-dgZ.gdZ/gde0ejbjezZ3gdZ4gdZ5gd Z6d!d"gZ7d#Z8d$Z9d%Z:d&Z;e:e8e;d'd(d)d*d+Z<Gd,d-e=Z>dWd.Z?eje?d/ZAd0ZBd1ZCd2ZDd3ZEd4ZFd5ZGd6ZHd7ZId8ZJdXd9ZKd:ZLd;ZMd<ZNd=ZOd>ZPd?ZQd@ZRdAZSidBeOdCeGdDddEddFeQdGddHeRdIddJeEdKeFdLddMdNdOddPddQeCdReSdSdePdeNdeMdeHeOdTeIddeJdU ZTdVZUy#e $reZd Zej<fZYVwxYw)Yz>Module to handle the operations within the aggregate pipeline.N)version)NOTHING)command_cursor) filtering)helpers)OperationFailure)InvalidDocument)Regex decimal128TF) $addToSet$avg$first$last$max $mergeObjects$min$push $stdDevPop $stdDevSamp$sum>$ln$abs$exp$ceil$sqrt$floor$log10$trunc>$log$mod$pow$divide $subtract$add $multiply) rrr rrr $arrayElemAtrr$switch$let$literal)z$dateFromString $dateToString$dateFromParts $dayOfMonth $dayOfWeek $dayOfYear$hourz $isoDayOfWeekz$isoWeekz $isoWeekYear $millisecond$minute$month$second$week$year$cond$ifNull) $concatArrays$filterz $indexOfArray$mapz$rangez$reducez $reverseArray$size$slicez$ziprz$meta)$concatz $indexOfBytesz $indexOfCP $regexMatch$split $strcasecmpz $strLenBytesz $strLenCP$substrz $substrBytesz $substrCP$toLower$toUpperz$trim)z$cmp$eq$ne)$and$or$not)$in $setEqualsz$setIntersectionz$setDifference $setUnionz $setIsSubsetz$anyElementTruez$allElementsTrue)z$convert $toString$toInt $toDecimal$toLong$arrayToObject$objectToArray $isNumber$isArrayc~td|D}|syt|ttt|z S)Nc3VK|]!}t|tjs|#ywN isinstancenumbersNumber.0vs \/var/lib/jenkins/workspace/mettalog/venv/lib/python3.12/site-packages/mongomock/aggregate.py z!_avg_operation..sJQJq'..,IqJ)))listsumfloatlen)values values_lists r^_avg_operationrgs7J&JJK  { eC[(9$:; ;;c<td|D}|sy||S)Nc3&K|] }|| ywrVr[s r^r_z#_group_operation..s:QAMq:s)ra)reoperatorrfs r^_group_operationrms#:&::K  K  rhct}trn|D]h}t|tjr|j |/t|t jsJ|j |jjntd|D}t|}t|tjrt j|S|S)Nc3VK|]!}t|tjs|#ywrVrWr[s r^r_z!_sum_operation..sN 1gnn0M1Nr`) radecimal_supportrXrYrZappendr Decimal128 to_decimalrbdecimalDecimal)rerfr] sum_values r^_sum_operationrws&KA!W^^,""1%Az445""1<<>2  NfNN K I/9)W__/U:  +d[ddrhclt}|D]$}t|ts|j|&|SrV)dictrXupdate)re merged_docr]s r^_merge_objects_operationr|s3J  a    a  rhc"t|tSrV)rmminres r^r +FC8rhc"t|tSrV)rmmaxrs r^rrrrhc|r|dSdSNrrkrs r^rrs&VAY:d:rhc|r|dSdS)Nrkrs r^rrs&F2J:d:rh)rr rrrrrceZdZdZddZdZdZdZdZdZ d Z d Z d Z d Z d ZdZdZdZdZdZdZdZdZy)_Parserz:Helper to parse expressions within the aggregate pipeline.Nc6||_||_|xsi|_yrV) _doc_dict_ignore_missing_keys _user_vars)selfdoc_dict user_varsignore_missing_keyss r^__init__z_Parser.__init__s!$7!#/rrhct|ts|j|St|dkDr+t d|Drt dt||fzi}|j D]\}}|tvr|j||cS|tvr|j||cS|tvr|j||cS|tvr|j||cS|tvr|j!||cS|t"vr|j%||cS|t&vr|j)||cS|t*vr|j-||cS|t.vr|j1||cS|t2vr|j5||cS|t6vr|j9||cS|t:vr|j=||cS|t>vr|jA||cS|tBtztDzvrtGd|z|jIdrt d|z |jK|}|||<|S#tL$r|jNrYwxYw)zParse a MongoDB expression.c3>K|]}|jdyw)$N) startswith)r\keys r^r_z _Parser.parse..s&Qss~~c':&Qszman expression specification must contain exactly one field, the name of the expression. Found %d fields in %szC'%s' is a valid operation but it is not supported by Mongomock yet.rzUnrecognized expression '%s')(rXry_parse_basic_expressionrdanyritemsarithmetic_operators_handle_arithmetic_operatorproject_operators_handle_project_operatorprojection_operators_handle_projection_operatorcomparison_operators_handle_comparison_operatordate_operators_handle_date_operatorarray_operators_handle_array_operatorconditional_operators_handle_conditional_operatorcontrol_flow_operators_handle_control_flow_operator set_operators_handle_set_operatorstring_operators_handle_string_operatortype_convertion_operators _handle_type_convertion_operatortype_operators_handle_type_operatorboolean_operators_handle_boolean_operatortext_search_operatorsobject_operatorsNotImplementedErrorrparseKeyErrorr)r expression value_dictkr]values r^rz _Parser.parsesq*d+// ; ; z?Q 3&Qj&Q#Q"Dz?J/01 1  $$&DAq((771==%%44Q::((771==((771==N"11!Q77O#221a88))88A>>**99!Q??M!00A66$$33Aq99--<.CsFet**51FsrHzuAlthough '%s' is a valid boolean operator for the aggregation pipeline, it is currently not implemented in Mongomock.)allrrr)rrlrers` r^rz _Parser._handle_boolean_operator?s v Gu++E2GH H u FvFF F v **622 2! ' (  HsA-cn|tvr |j|}|yt|tj st d|dt|d|dk(r t|S|dk(rtj|S|dk(rtj|S|dk(rtj|S|dk(rtj|S|d k(rtj|S|d k(rtj|S|d k(rtj |S|t"vrIt|t$t&fst d|d t|dt)|d k7rt d|z|j+|\}}||y|dk(r||z S|dk(rtj||S|dk(rtj,||S|dk(rtj.||S|dk(rt|t0j0r,t|t2t4frt1j6|}||z }t|t0j6rt9|j;dzS|St|t$t&fsJd|d t|dt'|j+|}|s Jd|z|D]*}|yt|tj r"Jd|z|dk(r t=|S|dk(rt?j@d|StCd|z#t$rYywxYw)Nz Parameter to z! must evaluate to a number, got ''rrrrrrrrz must evaluate to a list, got 'rz%s must have only 2 parametersr"rr r!r#) millisecondsz#%s must have at least one parameterz%s only uses numbersr$r%c ||zSrVrk)xys r^rz5_Parser._handle_arithmetic_operator..sQrhzxAlthough '%s' is a valid aritmetic operator for the aggregation pipeline, it is currently not implemented in Mongomock.)"unary_arithmetic_operatorsrrrXrYrZrtypeabsmathceilexpfloorloglog10sqrttruncbinary_arithmetic_operatorstuplerardrfmodpowdatetimeintrc timedeltaround total_secondsrb functoolsreducer) rrlrenumbernumber_0number_1res parsed_valuesrs r^rz#_Parser._handle_arithmetic_operatorMs- 1 1 F+~fgnn5&tF|-..6!6{"7"yy((6!xx''8#zz&))5 xx''8#zz&))7"yy((8#zz&)) 2 2fudm4&tF|-..6{a&'G('RSS!%!8 Hh8#39$(**6!xx(336!yy8446!xx(33;&h(9(9:"8c5\:'11xHH)c8#5#56 !2!2!4t!;<< &5$-0 [CKTRX\ Z [0T__V45 NChNN}"E}eW^^4 W6Lx6W W4# v }% % { "##$6 F F" GIQ RS SM  sL(( L43L4cL|tvr@t|tr|j|n|j |}t||S|dk(r-|\}}|j|}|j|} ||Std|z#t $r}t d|d}~wwxYw)Nr&z'Array have length less than index valueuAlthough '%s' is a valid project operator for the aggregation pipeline, it is currently not implemented in Mongomock.)_GROUPING_OPERATOR_MAPrXrrr IndexErrorrr)rrlrerrarrayindexerrors r^rz _Parser._handle_project_operators - -+5fc+BTZZ'X^H_F)(3F; ; ~ %JCJJsOEJJu%E UU|#"#24<#=> > UHIuT Us6B B# BB#c|dk(r|S|dk(rt|ts tddD] }||vstdj |t|dts td|dj Dcic]\}}||j |}}}t|jt|jfi||jj |d Std |zcc}}w) Nr)r(z,$let only supports an object as its argument)varsinzMissing '{}' parameter to $letrz,invalid parameter: expected an object (vars)rrr) rXryr rformatrrrrrrr)rrlrfieldvar_key var_valuers r^rz#_Parser._handle_projection_operators z !L v eT*%&TUU'%*+K+R+RSX+YZZ(eFmT2&'UVV+0-*=*=*?&GYI..IT__2 2$($=$=eE$K  ! "#24<#=> >sC6c4t|dk(sJd|j|d}|j|d}|dk(r||k(S|dk(r||k7S|tjvr(tjtj|||St d|z)Nrz#Comparison requires two expressionsrrrDrEzyAlthough '%s' is a valid comparison operator for the aggregation pipeline, it is currently not implemented in Mongomock.)rdrrSORTING_OPERATOR_MAP bson_comparer)rrlreabs r^rz#_Parser._handle_comparison_operators6{aF!FF JJvay ! JJvay ! u 6M u 6M y55 5)))*H*H*RTUWXY Y! ' () )rhc |dk(r.|j|}|t|jSdS|dk(r.|j|}|t|jSdS|dk(rHt |j |}d|vrdSdj |Dcgc] }t|c}S|dk(rt|dk7r td |j|d}|j|d }||yt|ts td t|ts td |j|S|d k(rt|d k7r tdt|j|d}|j|d }|j|d} |y|dkrtjdy| dkrtjd| dkr t|n|| z} ||| S|dk(rct|dk7r tdt|j|dt|j|d } } | | k(rdS| | krdSd S|dk(rt|tstdt!|zdD]} | |vstd| zt#|hdz }|rtdt |dz |j|d}t|ts td |j|d}d}|j%ddD]<}|dvrtd |zt't(|j}||}8||z}>t|tr1|t)j*|}nt)j*||}nd|vr|j,r td!t|t.j0r|r.|j,s"t)j*|j2|}n|j,t(j4t(j6zt(j8zt(j:zzrtd |j,z|}nt|t<r|j,t(j4t(j6zt(j8zt(j:zzrtd |j,zt)j*|j2|j,xs|}n td"t?|jA|StCd#|zcc}w#t$rYywxYw#t$rYywxYw#t$rYywxYw)$NrBrCr=r?rzsplit must have 2 itemsrrz,split first argument must evaluate to stringz-split second argument must evaluate to stringrAzsubstr must have 3 itemszuNegative starting point given to $substr is accepted only until MongoDB 3.7. This behavior will change in the future.zmNegative length given to $substr is accepted only until MongoDB 3.7. This behavior will change in the future.r@zstrcasecmp must have 2 itemsrr>z>$regexMatch expects an object of named arguments but found: %s)inputregexz#$regexMatch requires '%s' parameter>r r optionsz)$regexMatch found an unknown argument: %sr Fz.$regexMatch needs 'input' to be of type stringr r imxsz-$regexMatch invalid flag in regex options: %szJ$regexMatch: regex option(s) specified in both 'regex' and 'option' fieldsz7$regexMatch needs 'regex' to be of type string or regexzuAlthough '%s' is a valid string operator for the aggregation pipeline, it is currently not implemented in Mongomock.)"rrlowerupperrarjoinrdrrrX TypeErrorsplitwarningswarnryrsetgetgetattrrecompileflagsrRE_TYPEpatternIMXS _RE_TYPESboolsearchr)rrlreparsed parsed_listrstring delimiterfirstlengthsecondrrr unknown_args input_value regex_valr option re_optionr s r^rz_Parser._handle_string_operatorsT z !ZZ'F*0*<3v;$$& D" D z !ZZ'F*0*<3v;$$& D" D y tv67K;.4 ZBGG[ U,+U,/ U;:U;> V  V c Zt|trq|jddhk(r\|j|d}t j |d}|j tjj|}n|j|}|dk(r|jjS|dk(r |jS|dk(r|jdzdzS|d k(r |jS|d k(r |jS|d k(rt|j!d S|d k(r |j"S|dk(r |j$S|dk(r |j&S|dk(rt|j(dz S|dk(rt|ts t+dt|trddht-|ks t+dd|dvr t/dd|vr t/dd|jvr t/d|dj!|dS|dk(r t|tst+|dt1t-|ddhzdk7rt+|ddD]}||vst/d|d |d!|d}|j3d"dxsd}|j3d#dxsd} |j3d$d%xsd%} |j3d&d%xsd%} |j3d'd%xsd%} |j3d(d%xsd%} t5j4||| | | | | )St/d*|z)+Ndatetimezone)tzinfor.r,r-rr5r2r4z%Ur/r1r3r0rr*zP$dateToString operator must correspond a dictthat has "format" and "date" field.rz%LzqAlthough %L is a valid date format for the $dateToString operator, it is currently not implemented in Mongomock.onNullzoAlthough onNull is a valid field for the $dateToString operator, it is currently not implemented in Mongomock.zqAlthough timezone is a valid field for the $dateToString operator, it is currently not implemented in Mongomock.r+zH operator must correspond a dict that has "year" or "isoWeekYear" field.year isoWeekYear)r7isoWeek isoDayOfWeekr2z Although z is a valid field for the z8 operator, it is currently not implemented in Mongomock.monthdayhourrminuter* millisecond)r6r:r;r<r=r* microsecondzsAlthough '%s' is a valid date operator for the aggregation pipeline, it is currently not implemented in Mongomock.)rXrykeysrpytzr2replaceutc astimezone timetupletm_ydayr; isoweekdayr6r:rstrftimer<r=r*r?rrrrdrr)rrlrer target_tz out_valuerr6r:r;r<r=r*r>s r^rz_Parser._handle_date_operatorDs fd # &*9M(MJJvf~.E fZ&89I TXX 6AA)LI 6*I | #&&(00 0 } $== | #((*Q.!3 3 w >> ! x ?? " w y))$/0 0 w >> ! y ## # y ## # ~ %y,,t34 4  &fd+&:fd+Hf3EV3T&:y**)% 6!)% V[[]*)% V$--i.AB B ' 'i.&j!>>3y>V]$;;<A&j!>>PI%-#E7*D#*%((PV$DMM'1-2E--q).QC==+0qD]]8Q/41F]]8Q/41F#-- q9>QK$$' " ' () )rhc  |dk(rt|ttfs|g}t|j|}|D]>}|t|ttfrt dj t |d|vrdSttjj|S|dk(rt|ts t ddD]}||vst d|z|D]}|dvst d|z|j|d }||turyt|ttfst d t |z|jd d }|d }|D cgc]I} t|jt|j fi|| i|j"j%|Kc} S|dk(rt|tr*t'|dk7rt dt'|z|d}|j|} t| ttfs't d| turdzt | zt'| S|dk(rt|ts t dt)|hdz } | rt d| j+zd dht)|z } | rt d| j+z|j%|d }|jd d }|d} |D cgc]K} t|jt|j fi|| i|j"j%| r| Mc} S|dk(rot|ts t dt'|dkst'|dkDr#t dj t'||j%|d} t| ts#t d j t | t-d!|ddD]9\}}t|t.rt d"j |t |t'|dkDr%|ddkrt d#j |d|d}|dkr&t'|dkDrt'| |z|dz}nd}nt'|dkDr ||dz}n|}d}| ||St1d$|zcc} wcc} w)%Nr8z*$concatArrays only supports arrays, not {}r:z,$map only supports an object as its argument)r rzMissing '%s' parameter to $map>asrr z"Unrecognized parameter to $map: %sr z%input to $map must be an array not %srLthisrrr;rz>Expression $size takes exactly 1 arguments. %d were passed in.rz;The argument to $size must be an array, but was of type: %smissingr9z/$filter only supports an object as its argument>rLcondr z%Unrecognized parameter to $filter: %srOz!Missing '%s' parameter to $filterr<z+$slice only supports a list as its argumentrr zRExpression $slice takes at least 2 arguments, and at most 3, but {} were passed inz=First argument to $slice must be an array, but is of type: {})SecondThirdz9{} argument to $slice must be numeric, but is of type: {}z-Third argument to $slice must be positive: {}zsAlthough '%s' is a valid array operator for the aggregation pipeline, it is currently not implemented in Mongomock.)rXrarrrrr itertoolschain from_iterableryrrrrrrrrrdrpopziprr)rrlrr% parsed_itemr input_array fieldnamein_expritem array_value extra_paramsmissing_paramsrOnumr]startstops r^rz_Parser._handle_array_operators  &edE]3tu56K* *:kDRW=3Y*DKKDQ\L]^ +  ;.4 dD9V9VWb9c4d d v eT*&'UVV%E>*+Ka+OPP%11*+ORS+STT00w@K"kW&<kD%=9&'NQUVaQb'bcc $/IDkG(   NN>Y,=>(,(A(A%. !  w %&u:?*,@BEe*,MNNa007KkD%=9&Q"-"8YQRR>B;>OQRR{# # y eT*&'XYYu:(??L&'NQ]QaQaQc'cdd%v.U;N&'J^M_M_Ma'abb**U7^4K $/I=D!,NN>Y,=>(,(A(A%+   x eT*&'TUU5zA~Ua&(BBH&UBTVV**U1X.Kk40&SVD-.00159=Q!!S)*ST!W-//> 5zA~%(a-&(66{+e3eAh>DDUauQx'uT* *! & '( (YFs$AS8ASc |dk(rv |j|}t|trt |j St|t j r|jdddzSt |S|dk(ra |j|}tr>t|tjrt|jSt|Std|dk(ra |j|}tr>t|tjrt|jSt|Std|dk(rts td |j|}t|tr|durd nd }tj|}|St|tr tjt |}|St|trYtj d }tj t |j#|}tj|}|St|tjr|}|St|tr tj|}|St|t j rht j j)d }t ||z j+dzj-ddd }tj|}|St/dt1|z|dk(r |j|}|yt|t2t4fs#t'dj7t1|t9d|Dr|D cic] } | d| d c} St9d|Dr t;|St'd|dk(r |j|}|yt|t:t<j>fs#t'dj7t1|tA|dkDr!tBjDdkrtd|z|jGD cgc] \} } | | d c} } Std|z#t$rYywxYw#t$rYywxYw#t$rYywxYw#t$rYywxYw#tj$$r}t'd |z|d}~wwxYw#t$rYywxYwcc} w#t$rYywxYwcc} } w)NrLZrMzBYou need to import the pymongo library to support decimal128 type.rOrNT10z.00000000000000z_Failed to parse number '%s' in $convert with no onError value:Failed to parse string to decimalrr.rz'%s' type is not supportedrPz1$arrayToObject requires an array input, found: {}c3|K|]4}t|txrt|jddhk(6yw)rr]N)rXryrr@r\rs r^r_z;_Parser._handle_type_convertion_operator..|s2W1:a&F3qvvx=S#J+FFWs:<rr]c3hK|]*}t|ttfxrt|dk(,yw)rN)rXrarrdris r^r_z;_Parser._handle_type_convertion_operator..s+PA:a$/?CFaK?Ps02z`arrays used with $arrayToObject must contain documents with k and v fields or two-element arraysrQz2$objectToArray requires an object input, found: {})r zmAlthough '%s' is a valid type conversion, it is not implemented for Python 2 and Python 3.5 in Mongomock yet.)rr]z}Although '%s' is a valid type conversion operator for the aggregation pipeline, it is currently not implemented in Mongomock.)$rrrXr"rrr isoformatrpr rrrrsrrcrtruquantizeInvalidOperationrutcfromtimestamprrrrrarrrry collections OrderedDictrdsys version_infor) rrlrer$ decimal_valuererrepochstring_micro_secondsdrr]s r^rz(_Parser._handle_type_convertion_operator#s { " F+&$'6{((**&("3"34'')#2.44v;  x  F+fj&;&;<v002336{"%T  y  F+fj&;&;<v002336{"%T  | #")X F+&$' &$C * 5 5f = ,! +FC( * 5 5c&k B (! 'FE*oo&78 'F < E Ec J * 5 5m D ! FJ$9$9: & ! FC(O$.$9$9&$AM! FH$5$56 ))::1='*FUN+I+I+Kd+R'S'Y'YZ]_`'abc'd$ * 5 56J K !  DEFKNOO   8   AsQ<R (R R)(R8S"S1S6T< RR RR R&%R&) R54R58S SS" S.-S.6 TTc:|dk(r> |j|}t|trdSt|tj S|dk(r( |j|}t|t tfStd|z#t$rYywxYw#t$rYywxYw)NrRFrSzrAlthough '%s' is a valid type operator for the aggregation pipeline, it is currently not implemented in Mongomock.) rrrXr"rYrZrrar)rrlrer$s r^rz_Parser._handle_type_operators { " F+'vt45 \*VW^^:\ \ z ! F+fudm4 4! ,.6 78 8    s#A? B? B  B  BBc$|dk(r|dd}t|dkDrDtjtjtjdkr t d|d}|D]} |j|}||cS|j|S|dk(r^t|tr|\}}} nt|tr|d}|d}|d } |j} | rn } |j| Std |z#t $rYwxYw) Nr7rrz4.4zE$ifNull supports only one input expression in MongoDB v4.4 and lowerr6ifthenelsezzAlthough '%s' is a valid conditional operator for the aggregation pipeline, it is currently not implemented in Mongomock.) rdrr mongomockSERVER_VERSIONrrrXraryrr) rrlrefieldsfallbackrrJ condition true_case false_casecondition_valuers r^rz$_Parser._handle_conditional_operators5 y CR[F6{Q7==1I1I#Jgmm\aNb#b&1bzH $ 5 1I ,((- ::h' ' w &$'390 9jFD)"4L "6N #F^ "11)td |D],}|j|ds|j|d cSd |vr td |j|d Std |z)Nr'z4$switch requires an object as an argument, found: %sbranchesz3$switch expected an array for 'branches', found: %sz%$switch requires at least one branch.z7$switch expected each branch to be an object, found: %scasez5$switch requires each branch have a 'case' expressionr|z6$switch requires each branch have a 'then' expression.defaultzT$switch could not find a matching branch for an input, and no default was specified.zzAlthough '%s' is a valid control flow operator for the aggregation pipeline, it is currently not implemented in Mongomock.) rXryrrrrarrrr)rrlrerbranchs r^rz%_Parser._handle_control_flow_operatorsl y fd+& "&v,/ zz*b1Hhu 6& "&x.1&;#!&$/*$&*6l3'*O'*P##&&vf~6::fVn55#&&4::fY/0 0" & '( (rhc|dk(r'|\}}|j||j|vS|dk(r7g}|D].}|j|D]}||vs|j|0|S|dk(rM|Dcgc]}t|j|}}tj|dD] \} } | | k7s yyt d|zcc}w)NrIrKrJrFTzqAlthough '%s' is a valid set operator for the aggregation pipeline, it is currently not implemented in Mongomock.)rrqrrR combinationsr) rrlrerrresult set_valuer set_valuesset1set2s r^rz_Parser._handle_set_operator s u  & J::j)TZZ->> > { "F# !ZZ 2EF* e,3$M | #>DEU#djj/0EJE'44ZC d4< D! FHP QR R Fs2!C )NF)__name__ __module__ __qualname____doc__rrrrrrrrrrrrrrrrrrrrkrhr^rrstD* 5n   LS\>">0 )oSbb)Hy(v}(~8*)B1(fRrhrc:t||j|S)aParse an expression. Args: expression: an Aggregate Expression, see https://docs.mongodb.com/manual/meta/aggregation-quick-reference/#aggregation-expressions. doc_dict: the document on which to evaluate the expression. ignore_missing_keys: if True, missing keys evaluated by the expression are ignored silently if it is possible. r)rr)rrrs r^_parse_expressionr!s 81D E K KJ WWrhc i}|jD]\}}|dk(r |jD]\}}g}|D]} |jt|| |tvrt ||||<E|dk(r.g}d|D} | D]} | |vs|j| |||<x|dk(r||vr|||<||j ||t vrtd|ztd|z|S#t$rYwxYw)N_idr c3(K|] }|xsd ywrVrk)r\vals r^r_z$_accumulate_group..As8##++8srzqAlthough %s is a valid group operator for the aggregation pipeline, it is currently not implemented in Mongomock.z%s is not a valid group operator for the aggregation pipeline. See http://docs.mongodb.org/manual/meta/aggregation-quick-reference/ for a complete list of valid operators.)rrqrrrextendgroup_operatorsr) output_fields group_listrrrrlrredocval_itelts r^_accumulate_groupr1sIH%++- u E> "[[]MHcF!MM"3C"=>" 11"8"B6"J[(88!C%' S)"#(W$(&,HUOUO**62_,)$&./00 *'*22339+.H O9 sC44 D ?D cfd}|S)Nc|}t|tr.t|jDcgc] \}}||f c}}S|Scc}}wrV)rXrysortedr)rrrr] key_getters r^ fixed_getterz#_fix_sort_key..fixed_getter[sDo c4 )/ )<=v1QF= = >sA rk)rrs` r^ _fix_sort_keyrZs rhcBdD]}||vstd|zdD]m}||vrtd|zt||ts td|dvr||j dr td|d k(s\d ||vsdtd |d }|d }|d}|d }|j |}|D]S} t j| |} t| trd| i} |j|| i} | D cgc]} | c} | |<U|S#t$rd} YKwxYwcc} w)N)letpipelineztAlthough '%s' is a valid lookup operator for the aggregation pipeline, it is currently not implemented in Mongomock.)from localField foreignFieldrLz%Must specify '%s' field for a $lookupz$Arguments to $lookup must be strings)rLrrr,FieldPath field names may not start with '$'rLrgzAlthough '.' is valid in the 'as' parameters for the lookup stage of the aggregation pipeline, it is currently not implemented in Mongomock.rrrrI) rrrXrrget_collectionrrrrafind) in_collectiondatabaser rl foreign_name local_field foreign_field local_nameforeign_collectionrquerymatches foreign_docs r^_handle_lookup_stagerds' w %,.678 8( A 7 ""7(BD D'(+S1"68 8 ; ;!,,S1">@ @ t wx((%JK KA$6?L,'KN+MJ!00> ,,S+>E eT "ENE$))=%*@A:AB;;BJ  E  Cs7D 8 D DDc#K|j|d}|dd}|s|yt|ttfr|D]}t ||D]}|yt|t rt ||D]}|yyw)Nrr)rrXrar_recursive_getry)match nested_fieldsheadremaining_fieldsmanswers r^rrs 99]1% &D$QR(  $u &A(,<= > D$ $T+;._find_matches_for_depths eT "ENE$))+;U*CD  I''(BIN!%( ;* + 7 7 ZkSXEY ZI""9- % 01 !rhr)rXrrrryrrrrcopydeepcopyrrrrr)rrr rlr start_withconnect_from_fieldr max_depthout_docrrrorigin_matchesnewly_discovered_matchesrr match_targetrrrrrrs @@@@@@r^_handle_graph_lookup_stagers gkk*a0# 6 BD D gkk";R@$ G UW W gkk,3S 9 DF F'! ?A AH 7 ""IK K 8  ' ' ,"#QR R t wx'8 8%JLTUV VI6?L%J !34/0J J-I++lD1K!(-F!K!00>mmM*G  e  &z37F,C6+JJZ)"3uy7H QJE') $' 2 8 8 = $25-$HL,0G 0UU,%I(  O7 7O5N)"3uy7H" N   s H H&%H&c g}|d r. fd fd}t||}tj| }nd|fg}|D]6\}}|D cgc]} | } } t|| } || d<|j | 8|Scc} w)Nrc@ t|dS#t$rYywxYw)NTr)rr)rrs r^ _key_getterz(_handle_group_stage.._key_getters) (ctLL  s  c:tj|SrV)rBsonComparable)rrs r^_sort_key_getterz-_handle_group_stage.._sort_key_getters++K,<= =rhr)rrRgroupbyrrq)runused_databaser grouped_collectionrsorted_collectiongroupeddoc_idgrouprrrrrs @@r^_handle_group_stagers %.C    > #=6FG##$5{C-() "'(Qq( ($Wj9 !!(+ !  )s A<cthdz }|rtd|jzdvsdvr tdddttstdt zt dkrtdt ztk7r td jd d d d ii}jdd} |dk\fdfdfd|D}t|d}tj|d}g}|D]<\\}} } | D cgc]} | d  } } t|| } | | d<|j| >|S#t$rdYwxYwcc} w)N>outputrgroupBy boundariesz#Unrecognized option to $bucket: %s.rrz<$bucket requires 'groupBy' and 'boundaries' to be specified.zCThe $bucket 'boundaries' field must be an array, but found type: %srzRThe $bucket 'boundaries' field must have at least 2 values, but found %d value(s).zDThe 'boundaries' option to $bucket must be sorted in ascending orderrcountrrrrTcJ dS#t$r}td|d}~wwxYw)NrzT$bucket could not find a matching branch for an input, and no default was specified.)rr)rur s r^_get_default_bucketz1_handle_bucket_stage.._get_default_bucket%s< D9% % D":;@C D Ds " "c t|}tj|}|r|t kr d|dz fSfS#t$r fcYSwxYw)zGet the bucket ID for a document. Note that it actually returns a tuple with the first param being a sort key to sort the default bucket even if it's not the same type as the boundaries. Fr)rrbisect bisect_rightrd)rrrrrgroup_byis_default_lasts r^_get_bucket_idz,_handle_bucket_stage.._get_bucket_id-sy <%h4E##J6 US_,:eai01 1!4!677  <#%8%:; ; .=sICnS)3/Isc |dSrrkkvs r^rz&_handle_bucket_stage..>s"Q%rhrc |dSrrkrs r^rz&_handle_bucket_stage..?s2a5rhr)rrrUrXrarrdrrrrRrrrq)rrr unknown_optionsr default_valueout_collectionr unused_keyrrrrrrrrrrs ` @@@@@r^_handle_bucket_stager s'l%SSO 1O4G4G4I IK K JL Ly!H&J j$ ' Q:    : !#&z? 34 4jZ' RT TKK7VQK*@AMKK 40M':b>9D8 J=IMM/?@N0@AGN'.#Ve&+,be, ,$]J? h' (/ K B-s E*6 E;* E87E8ct|ts td|jdd}| td|r%tdt |jzt |}t j||d|S)Nz1the $sample stage specification must be an objectsizez!$sample stage must specify a sizez"unrecognized option to $sample: %s)rXryrrUrra_randomshuffle)rrr r shuffleds r^_handle_sample_stager Js| gt $RSS ;;vt $D |BCCCc'lFVFVFXXYYM"H OOH ET?rhc t|jDcgc] \}}||i c}}}|}|D].}|jD]\ }t| fd|dk}0|Scc}}w)Nc0tj|SrV)rresolve_sort_key)rsortKeys r^rz$_handle_sort_stage..^si88!Drhr)rreverse)reversedrr) rrr rr sort_arrayr sort_pair sortDirectionrs @r^_handle_sort_stagerWsrgmmo>daAq6>?J% &/oo&7 "G] &!D%)!+ '8 ?sA' ct|tsd|i}|d}t|tr|ddk7rtd|z|dd}|j d}|j d}g}|D]} t j ||}||r|j|0|gk(r?|r {'a': 1, 'b': {'c': 1, 'd': 1}} rgrzcInvalid $project :: caused by :: specification contains two conflicting paths. Cannot specify both z and z: rc 3NK|]\}}|t||dfyw)rg)prefixN)_combine_projection_spec)r\rr]original_filterr)s r^r_z+_combine_projection_spec..s2# Aq $Q6ST@U VW#s"%) rXrarprq partitionrrreprr) filter_listr+r) filter_dictrr separatorsubkey other_keys `` r^r*r*s> k4 ())+K#&==#5 y&+//%0$7!CK+e*u~"'YYF y 5E>"BDKLM My U"LNUVW W ' '~""5) $:G$HJR$H !$H"=2GHOFG !25&VZ![ I%(0 )5!8!LZ1_M5! $$/{GTO!  o&I:MNNN,AB 1 LaL   3%I     s$ D?,E8E#E EEc|s td|Dcgc] }t|}}|jD]}\}}t||D]i\}} t ||d} |j d} | ddD]4} |j| i|| <t|| tsi|| <|| }6| || d<k|Scc}w#t $rYwxYw)NzMInvalid $addFields :: caused by :: specification must have at least one fieldTrrgr) rryrrVrrrrrX) rrr rrrrrBrrJpartssubfields r^_handle_add_fields_stagerHs  [] ]+89Cd3i9N9  u"=.AOFG -eVQUV KK$E!#2J$+KK"$=!!'("3T:(*GH%!(+ ' "+GE"I  B( :   sB8B== C C c|j|}|jr|j|r|j||SrV)rfind_onedrop insert_many)rrr rs r^_handle_out_stagerM%sA,,W5N ""=1 rhct|tr|dk(r td|jdr tdd|vr td|t |igS)Nrz*the count field must be a non-empty stringrz+the count field cannot be a $-prefixed pathrgz"the count field cannot contain '.')rXrrrrd)rrr s r^_handle_count_stagerO/s^ gs #w"}KLL   C LMM CDD c-( ) **rhc pi}|jD]\}}tt|||d||<!|gSrV)rraprocess_pipeline)rrr out_collection_by_pipelinepipeline_titlers r^_handle_facet_stagerT9sI!#$+MMO 59:J 8Xt;566">2%4 ' ''rhc tj|}|Dcgc]-}tj|tj|r|/c}Scc}wrV)r$patch_datetime_awareness_in_documentrr)rrr specrs r^_handle_match_stagerXAsN  7 7 @D$   # #D'*V*VWZ*[ \   s2Az $addFieldsz$bucketz $bucketAutoz $collStatsz$countz $currentOpz$facetz$geoNearz $graphLookupz$groupz $indexStatsz$limitc |d|SrVrkcrxos r^rrUs aerhz$listLocalSessionsz $listSessionsz$lookupz$matchz$mergec ||dSrVrkrZs r^rrcs QqrUrh) z$outz$planCacheStatsz$projectz$redactz $replaceRootz $replaceWithz$samplez$setz$skipz$sortz $sortByCountz$unsetz$unwindc |r td|D]>}|jD])\}} t|}|std|z||||}+@t j |S#t$r}td|z|d}~wwxYw)Nz&Mongomock does not handle sessions yetz%s is not a valid operator for the aggregation pipeline. See http://docs.mongodb.org/manual/meta/aggregation-quick-reference/ for a complete list of valid operators.zmAlthough '%s' is a valid operator for the aggregation pipeline, it is currently not implemented in Mongomock.)rr_PIPELINE_HANDLERSrr CommandCursor) collectionrrsessionstagerlr handlerrus r^rQrQks!"JKK!& Hg S,X6 )>@HIJJ!Xw?J"/  ' ' 33 S)>@HIJPSS Ss A&& B/A>>B)F)r)VrrrprrrtrrRrrY packagingrrandomrrrrrA sentinelsrr~rrrr bson.errorsr bsonr r rprr! ImportErrorRandomr rrrrrrrrrrrrrrarr@rrrrrrgrmrwr|robjectrrregister_parse_expressionrrrrrrrr rr&r*r4r:rDrHrMrOrTrXr_rQrkrhr^rnsOD     $&#+&O%(I &--/  24OO S  $!), !    ' ' , , ./ 0 ,   <! e  - 8 8: :@ Rf@ RF X$ ##$56&R(V&FR<>B  )\D0$0f*+(* #4$   !  $  !. !4 #$T#  !!" d#$ %.# $ " #=D4W2#&OO"I#s$F??GG