[SERVER-15164] positional operator element mismatch when using both $slice and $ projections Created: 07/Sep/14  Updated: 15/Nov/19  Resolved: 15/Nov/19

Status: Closed
Project: Core Server
Component/s: Querying
Affects Version/s: 2.4.8, 2.6.4, 2.7.6
Fix Version/s: 4.3.2

Type: Bug Priority: Major - P3
Reporter: NOVALUE Mitar Assignee: Ian Boros
Resolution: Done Votes: 1
Labels: query-44-grooming
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Related
related to SERVER-6864 positional operator projection inclus... Closed
Backwards Compatibility: Fully Compatible
Operating System: ALL
Steps To Reproduce:

You insert a document with two array fields:

db.test.insert( { "importing" : [ { "foo": "a" }, { "foo": "b" } ], "jobs" : [ { "status" : "completed" } ] } )

You try to query it, where you use $slice on one, and $ on another. The query should match the second element in importing, which does not exist in jobs:

db.test.find( { "importing.foo": "b" }, { jobs: { '$slice': -1 }, 'importing.$': 1 })

You get:

error: { "$err" : "positional operator element mismatch", "code" : 16353 }

Sprint: Query 2019-11-18, Query 2019-12-02
Participants:

 Description   

It is not possible to use both $slice and $ projections, even if they are on separate fields.



 Comments   
Comment by Ian Boros [ 15/Nov/19 ]

It looks like this was fixed "for free" during our work to unify the projection implementations. Added a test and now closing.

Comment by Githook User [ 14/Nov/19 ]

Author:

{'name': 'Ian Boros', 'username': 'puppyofkosh', 'email': 'ian.boros@mongodb.com'}

Message: SERVER-15164 test that positional operator and $slice can be used in the same projection
Branch: master
https://github.com/mongodb/mongo/commit/cdc44d95e169da75093f25c324aa9670e72743e8

Comment by NOVALUE Mitar [ 06/Aug/19 ]

No worries. Glad to hear you are working on/discussing cleaning this a bit.

Comment by Ian Boros [ 06/Aug/19 ]

mitar,

I actually mistook this example for a separate quirk in the interaction between $slice and positional projection which I'd been discussing with another query team member recently. I didn't mean to alarm you.

Comment by NOVALUE Mitar [ 06/Aug/19 ]

Oh, I just now noticed this.

Why would you end up banning this? Those things operate on completely unrelated things? Why would slicing in projection on one field prevent work on the other.

The workaround is problematic because it requires one to duplicate the query in the projection. This is tricky if you are generating queries automatically. For example, imagine that you have a query builder for an user. You have a select query part, and then user selects which fields to select. The last in jobs, and whatever was matched in query. Now you have to detect that there is a slice in jobs and change the importing projection to $elemMatch? Or should you then always use $elemMatch repeating the search condition? But then you have to parse the query and rewrite it into $elemMatch?

What is the purpose of having $ in the projection then, if it fails on more complicated projections?

Comment by Ian Boros [ 06/Aug/19 ]

Sounds good. I suspect we'll end up banning this.

Comment by Asya Kamsky [ 07/Sep/14 ]

You can use the $elemMatch projection operator to get the result you want:

db.test.find( { "importing.foo": "b" },   { jobs: { '$slice': -1 },  'importing' : { "$elemMatch" : { "foo" : "b" } }  }  )
{ "_id" : ObjectId("540cdf10ce5fcf3db923f4d1"), "importing" : [ { "foo" : "b" } ], "jobs" : [ { "status" : "completed" } ] }

Generated at Thu Feb 08 03:37:09 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.