Details

    • Type: New Feature
    • Status: In Code Review
    • Priority: Major - P3
    • Resolution: Unresolved
    • Affects Version/s: None
    • Fix Version/s: 3.1.6
    • Component/s: Querying
    • Labels:
    • Environment:
      All

      Description

      We've decided to implement a few bit-test query operators:

      $bitsAllSet - matches if the input bit positions are all 1
      $bitsAllClear - matches if the input bit positions are all 0
      $bitsAnySet - matches if any of the bit positions are 1
      $bitsAnyClear - matches if any of the bit positions are 0

      These operators can take an array of bit positions, a 64-bit number bitmask, or a BinData bitmask. For the number and BinData bitmasks, the bit positions to check are the positions of 1's in their binary representation.

      The operators will only match against int32, int64, doubles, and binary data. Other types will not match.

      Note that bit position 0 means the least significant bit.

      An example using the array of bit positions syntax:

      db.foo.insert( { a: 43 } ); // Binary form: 101011 (leading zeroes truncated)
      db.foo.find( { a: { $bitsAllSet: [0, 1, 3] } }, { _id: 0, a: 1 } );
      Result: { a: 43 }
      

      An example using the bitmask syntax:

      db.foo.insert( { a: 43 } ); // Binary form: 101011 (leading zeroes truncated)
      db.foo.find( { a: { $bitsAllSet: 9 } }, { _id: 0, a: 1 } ); // Binary form of the bitmask: 1001
      Result: { a: 43 }
      

        Issue Links

          Activity

          Hide
          qingyang.chen Qingyang Chen added a comment -

          Hi guipulsar: This feature is planned and under development. I have updated the description of the ticket to reflect what we have decided to implement.

          Show
          qingyang.chen Qingyang Chen added a comment - Hi guipulsar : This feature is planned and under development. I have updated the description of the ticket to reflect what we have decided to implement.
          Hide
          nifan nifan added a comment - - edited

          Let's be careful that the documentation will reflect that this is 1-based not 0-based.

          One might expect it would be 0-based.
          Given that A is an int which gets used as a bit array and arrays normally being indexed starting at 0 not 1.

          db.foo.insert( { a: 54 } ); // Binary form: 110110 (leading zeroes truncated)
          db.foo.find( { a: { $bitsAllSet: [0, 1, 3, 4] } }, { _id: 0, a: 1 } );
          Result: { a: 54 }
          

          Show
          nifan nifan added a comment - - edited Let's be careful that the documentation will reflect that this is 1-based not 0-based. One might expect it would be 0-based. Given that A is an int which gets used as a bit array and arrays normally being indexed starting at 0 not 1. db.foo.insert( { a: 54 } ); // Binary form: 110110 (leading zeroes truncated) db.foo.find( { a: { $bitsAllSet: [0, 1, 3, 4] } }, { _id: 0, a: 1 } ); Result: { a: 54 }
          Hide
          david.storch David Storch added a comment -

          nifan, I believe that the bit positions are zero-based, not one-based. The following shows the indexes of each bit for the binary representation of 54:

          Binary representation: 110110
                    Bit indexes: 543210
          

          This is why 54 matches when you ask for bit positions 1, 2, 4, and 5. Does this clarify the specification of the feature?

          Best,
          Dave

          Show
          david.storch David Storch added a comment - nifan , I believe that the bit positions are zero-based, not one-based. The following shows the indexes of each bit for the binary representation of 54: Binary representation: 110110 Bit indexes: 543210 This is why 54 matches when you ask for bit positions 1, 2, 4, and 5. Does this clarify the specification of the feature? Best, Dave
          Hide
          nifan nifan added a comment -

          Ah I was assuming using the most significant bit first. (going left to right)
          But this implementation makes more sense.

          Can we chose a different example ? for example 43:

          Binary representation: 101011
                           Bit indexes: 543210
          

          db.foo.insert( { a: 43 } ); // Binary form: 101011 (leading zeroes truncated)
          db.foo.find( { a: { $bitsAllSet: [0, 1, 3] } }, { _id: 0, a: 1 } );
          Result: { a: 43 }
          

          That example is would have only one way to interpret the result I think.

          I also removed the 5'th bit position to indicate that not all the indexes have to be specified to match 43.

          Show
          nifan nifan added a comment - Ah I was assuming using the most significant bit first. (going left to right) But this implementation makes more sense. Can we chose a different example ? for example 43: Binary representation: 101011 Bit indexes: 543210 db.foo.insert( { a: 43 } ); // Binary form: 101011 (leading zeroes truncated) db.foo.find( { a: { $bitsAllSet: [0, 1, 3] } }, { _id: 0, a: 1 } ); Result: { a: 43 } That example is would have only one way to interpret the result I think. I also removed the 5'th bit position to indicate that not all the indexes have to be specified to match 43.
          Hide
          david.storch David Storch added a comment -

          nifan, thanks! I updated the description based on your example.

          Show
          david.storch David Storch added a comment - nifan , thanks! I updated the description based on your example.

            Dates

            • Created:
              Updated:
              Days since reply:
              5 hours, 56 minutes ago
              Date of 1st Reply:

              Agile