Core Server
  1. Core Server
  2. SERVER-2363

$push/$pushAll support for insertion at any position (top/bottom/ordinal)

    Details

    • Type: Improvement Improvement
    • Status: Closed Closed
    • Priority: Minor - P4 Minor - P4
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 2.5.3
    • Component/s: Write Ops
    • Labels:
      None
    • Backport:
      No
    • # Replies:
      9
    • Last comment by Customer:
      false
    • Driver changes needed?:
      Driver changes needed

      Description

      Add $position option which takes a positive number.

      db.col.save({_id:1, a: [3]})
      db.col.update({}, {$push: {a: {$each:[1,2], $position:0 }}}) // pushes to front of array
      

      If $position is equal to or greater than the array size then it will be ignored and is effectively a push to the end, which is the default behavior if not specified.

      This will allow you to effectively $pop from the top and add to the bottom or vice versa using $slice since you push in either direction.

        Issue Links

          Activity

          Hide
          Keith Branton
          added a comment -

          This duplicates much of my ticket: http://jira.mongodb.org/browse/SERVER-2362

          I already requested $unshift with $each support on that ticket which would take care of $push and $pushAll insertion at top. -1 for changing $pushAll at all - it should be deprecated in favor of $push with $each, not enhanced.

          Since $push looks like { $push :

          { field : value }

          } it's hard to see how that could be changed to support insertion in the top while maintaining backwards compatibility in an elegant way or semantic correctness.

          I'm not sure I understand the benefit of this proposal wrt $addToSet. Is there a use-case that the current $addToSet, and proposed $pushToSet and $unshiftToSet modifiers wouldn't satisfy? I have documented a couple on 2363 that this proposal would certainly not satisfy.

          Show
          Keith Branton
          added a comment - This duplicates much of my ticket: http://jira.mongodb.org/browse/SERVER-2362 I already requested $unshift with $each support on that ticket which would take care of $push and $pushAll insertion at top. -1 for changing $pushAll at all - it should be deprecated in favor of $push with $each, not enhanced. Since $push looks like { $push : { field : value } } it's hard to see how that could be changed to support insertion in the top while maintaining backwards compatibility in an elegant way or semantic correctness. I'm not sure I understand the benefit of this proposal wrt $addToSet. Is there a use-case that the current $addToSet, and proposed $pushToSet and $unshiftToSet modifiers wouldn't satisfy? I have documented a couple on 2363 that this proposal would certainly not satisfy.
          Hide
          Scott Hernandez
          added a comment -

          This issue is independent of your issue/proposal; I am not making the assumption that what your propose will every come to be, or is even good. I'm just asking for improvements to the current features.

          There are many ways to keep backwards compatibility. We can add $pushToTop to the update, or to the $push document.

          (I don't like $(un)shift*; it is not intuitive. $push with a modifier for direction seems very simple, and works, rather than a new operator/modifier.)

          Show
          Scott Hernandez
          added a comment - This issue is independent of your issue/proposal; I am not making the assumption that what your propose will every come to be, or is even good. I'm just asking for improvements to the current features. There are many ways to keep backwards compatibility. We can add $pushToTop to the update, or to the $push document. (I don't like $(un)shift*; it is not intuitive. $push with a modifier for direction seems very simple, and works, rather than a new operator/modifier.)
          Hide
          Keith Branton
          added a comment -

          @Scott - I'm not aware of any other uses for push in programming besides stacks. In stack semantics "push" means "add item to top of stack". The current $push operation is consistent with this. The deque is the data structure that supports adding and removing at both ends. The most common names for deque operations in modern languages are $push/$pop/$unshift/$shift. These are at least common to javascript, ruby, PHP (with array_ prefix) and perl. Since Mongo already uses $push and $pop, it makes sense to keep the operations at the other end of the structure consistent with the languages that use push and pop.

          Since $push adds an item to the end of an array, it seems that the end of the array is the top, and the front must, therefore, be the bottom. So $pushToTop would be a very misleading name for an operation that adds an item to the bottom.

          I believe good naming, consistent with common CS concepts, is much more intuitive and lowers the barrier to entry for newbies, but honestly I'm not so concerned with what the modifiers ultimately get called I'm not really a big fan of the names $shift and $unshift either - but I am a very big fan of consistency.

          Show
          Keith Branton
          added a comment - @Scott - I'm not aware of any other uses for push in programming besides stacks. In stack semantics "push" means "add item to top of stack". The current $push operation is consistent with this. The deque is the data structure that supports adding and removing at both ends. The most common names for deque operations in modern languages are $push/$pop/$unshift/$shift. These are at least common to javascript, ruby, PHP (with array_ prefix) and perl. Since Mongo already uses $push and $pop, it makes sense to keep the operations at the other end of the structure consistent with the languages that use push and pop. Since $push adds an item to the end of an array, it seems that the end of the array is the top, and the front must, therefore, be the bottom. So $pushToTop would be a very misleading name for an operation that adds an item to the bottom. I believe good naming, consistent with common CS concepts, is much more intuitive and lowers the barrier to entry for newbies, but honestly I'm not so concerned with what the modifiers ultimately get called I'm not really a big fan of the names $shift and $unshift either - but I am a very big fan of consistency.
          Hide
          Eliot Horowitz
          added a comment -

          Not sure if both will happen or one, but marked as related .

          Show
          Eliot Horowitz
          added a comment - Not sure if both will happen or one, but marked as related .
          Hide
          Aaron Heckmann (Inactive)
          added a comment -

          Agree with $push/$pop/$unshift/$shift semantics being intuitive.

          Show
          Aaron Heckmann (Inactive)
          added a comment - Agree with $push/$pop/$unshift/$shift semantics being intuitive.
          Hide
          Jan Riechers
          added a comment - - edited

          Hello,

          would it be possible to integrate a $pushAt, $popFrom queries, meaning:
          $pushAt - pushes an item to a specific position (most likely an array)
          $popFrom - removes an item from a given position
          both methods should require of course a position operator - most likely an array?

          At the moment "$pull" removes/searches for many values inside an array, but if there is only one (surely) item to be removed, perhaps it would be more performant to have something like
          "$pullOne" or similiar and then exit the operation without touching any subsequent items of an array to increase performance in difference to ordinary "$pull" (seeking through all elements)

          Is this possible?

          Show
          Jan Riechers
          added a comment - - edited Hello, would it be possible to integrate a $pushAt, $popFrom queries, meaning: $pushAt - pushes an item to a specific position (most likely an array) $popFrom - removes an item from a given position both methods should require of course a position operator - most likely an array? At the moment "$pull" removes/searches for many values inside an array, but if there is only one (surely) item to be removed, perhaps it would be more performant to have something like "$pullOne" or similiar and then exit the operation without touching any subsequent items of an array to increase performance in difference to ordinary "$pull" (seeking through all elements) Is this possible?
          Hide
          Artem
          added a comment -

          Jan +1 I want $pushAt and $popFrom too. Have you voted for this issue? We need to get more votes to move this issue from "planned but not scheduled" to "Planning Bucket A"

          Show
          Artem
          added a comment - Jan +1 I want $pushAt and $popFrom too. Have you voted for this issue? We need to get more votes to move this issue from "planned but not scheduled" to "Planning Bucket A"
          Hide
          Jan Riechers
          added a comment - - edited

          Artem, I just added my vote, but perhaps it's also a good idea to push this ticket info (with short summary onto the mailinglist?) to get attention to it. Also my proposal differs somehow from the initial post and it might be kinda misleading to what is beeing voted for.

          I personally don't agree with shift/unshift in total, for me it takes more understanding, from a stack/array logic point of view, to understand those and I see those in a broader concept: (not onlty top/bottom)

          Idea for me:
          "$shift" -> shifts any item in question by the stack by (possible negative value for updwards) X positions from current position, either finding it by direct addressing it as 'Item2', or by positional index - if the position is out of reach, the item just drops to the end of the list.

          But this way of course assumes, that you exactly know the position of the element to be moved, and this can of course change if the current information is outdated and there are no reference counters (probably a bad idea, I dunno).
          On the other hand, if one wants a dynamic increasing stack (forwards and backwards) - shifting with "null" value inserts could also be desired, but perhaps sometimes not of course..

          Thats why I came up with the examples
          $pushAt, $popFrom, $pullOnce - cause one can

          in heavy updated documents:
          $pushAt" -> Pushes at exact positon, $pullOnce - removes one existing, but unique, value from the stack/array

          But of course, keeping track of an object position - for example by referencing a index position is kinda risky - assuming anohter element gets pushed at the same position - but we don't track the previous item has moved one forward (down) in the array. But this might also depend on the use case and $pullOnce may come into play.

          in single documents not affected by massive changes:
          "$popFrom" -> If we we are safe with a document, we tell mongo exactly which position to be removed,
          of course also the "$pullOnce" solution can be used, but this involves scanning data - which might be not neccesary - but I agree that this command is quite special as most of the time one not might know beforehand the actual positon of one item so.

          Anyhow, sorry for this long post so, but I hope it makes sense.

          Show
          Jan Riechers
          added a comment - - edited Artem, I just added my vote, but perhaps it's also a good idea to push this ticket info (with short summary onto the mailinglist?) to get attention to it. Also my proposal differs somehow from the initial post and it might be kinda misleading to what is beeing voted for. I personally don't agree with shift/unshift in total, for me it takes more understanding, from a stack/array logic point of view, to understand those and I see those in a broader concept: (not onlty top/bottom) Idea for me: "$shift" -> shifts any item in question by the stack by (possible negative value for updwards) X positions from current position, either finding it by direct addressing it as 'Item2', or by positional index - if the position is out of reach, the item just drops to the end of the list. But this way of course assumes, that you exactly know the position of the element to be moved, and this can of course change if the current information is outdated and there are no reference counters (probably a bad idea, I dunno). On the other hand, if one wants a dynamic increasing stack (forwards and backwards) - shifting with "null" value inserts could also be desired, but perhaps sometimes not of course.. Thats why I came up with the examples $pushAt, $popFrom, $pullOnce - cause one can in heavy updated documents: $pushAt" -> Pushes at exact positon, $pullOnce - removes one existing, but unique, value from the stack/array But of course, keeping track of an object position - for example by referencing a index position is kinda risky - assuming anohter element gets pushed at the same position - but we don't track the previous item has moved one forward (down) in the array. But this might also depend on the use case and $pullOnce may come into play. in single documents not affected by massive changes: "$popFrom" -> If we we are safe with a document, we tell mongo exactly which position to be removed, of course also the "$pullOnce" solution can be used, but this involves scanning data - which might be not neccesary - but I agree that this command is quite special as most of the time one not might know beforehand the actual positon of one item so. Anyhow, sorry for this long post so, but I hope it makes sense.
          Hide
          auto
          added a comment -

          Author:

          {u'username': u'scotthernandez', u'name': u'Scott Hernandez', u'email': u'scotthernandez@gmail.com'}

          Message: SERVER-2363 $push support for insertion at any position
          Branch: master
          https://github.com/mongodb/mongo/commit/967dbe1b27ac6459c15d02c30dd6a0790203d54e

          Show
          auto
          added a comment - Author: {u'username': u'scotthernandez', u'name': u'Scott Hernandez', u'email': u'scotthernandez@gmail.com'} Message: SERVER-2363 $push support for insertion at any position Branch: master https://github.com/mongodb/mongo/commit/967dbe1b27ac6459c15d02c30dd6a0790203d54e

            People

            • Votes:
              8 Vote for this issue
              Watchers:
              11 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Days since reply:
                27 weeks, 5 days ago
                Date of 1st Reply: