Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOCSP-34044: Add bitwise operators to aggregation pipeline #253

Open
wants to merge 18 commits into
base: master
Choose a base branch
from
Open
165 changes: 161 additions & 4 deletions source/fundamentals/linq.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ LINQ
.. contents:: On this page
:local:
:backlinks: none
:depth: 2
:depth: 3
:class: singlecol

.. facet::
Expand Down Expand Up @@ -68,10 +68,11 @@ object that links to the collection. To create the object, use the ``AsQueryable
as follows:

.. code-block:: csharp
:emphasize-lines: 2
:emphasize-lines: 3

var restaurantsCollection = restaurantsDatabase.GetCollection<Restaurant>("restaurants");
var queryableCollection = restaurantsCollection.AsQueryable();
var restaurantsDatabase = client.GetDatabase("sample_restaurants");
var restaurantsCollection = restaurantsDatabase.GetCollection<Restaurant>("restaurants");
var queryableCollection = restaurantsCollection.AsQueryable();

The ``AsQueryable()`` method returns an `IMongoQueryable
<{+new-api-root+}/MongoDB.Driver/MongoDB.Driver.Linq.IMongoQueryable.html>`__ instance that
Expand Down Expand Up @@ -587,6 +588,162 @@ in the Atlas manual. For more examples about running Atlas Vector Search queries
{+driver-short+}, see :atlas:`Run Vector Search Queries </atlas-vector-search/vector-search-stage/>`
in the Atlas manual and select :guilabel:`C#` from the language dropdown.

Bitwise Operators
~~~~~~~~~~~~~~~~~

The following section describes the `bitwise operators <https://en.wikipedia.org/wiki/Bitwise_operation>`__
mayaraman19 marked this conversation as resolved.
Show resolved Hide resolved
supported by the {+driver-short+} that you can use in an aggregation pipeline.
You can use multiple bitwise operators in the same
stage. The following guidelines apply when using bitwise operators:

- All operands must be of type ``int`` or ``long``.

- ``$bitAnd``, ``$bitOr``, and ``$bitXor`` all take two or more operands. ``$bitNot`` can only take one operand.
mayaraman19 marked this conversation as resolved.
Show resolved Hide resolved

- The bitwise operation will be evaluated from left to right.
mayaraman19 marked this conversation as resolved.
Show resolved Hide resolved

The examples for this section use the following documents in a collection called
mayaraman19 marked this conversation as resolved.
Show resolved Hide resolved
``ingredients``:

.. code-block:: json

{ "_id": 1, "name": "watermelon", "price": 5, "count": 1 },
{ "_id": 2, "name": "onions", "price": 2, "count": 4 },
{ "_id": 3, "name": "eggs", "price": 5, "count": 12 },
{ "_id": 4, "name": "potatoes", "price": 3, "count": 0 },
{ "_id": 5, "name": "pasta", "price": 4, "count": 100 },
{ "_id": 6, "name": "cheese", "price": 4 }

The following ``Ingredient`` class models the documents in the ``ingredients``
collection:

.. literalinclude:: /includes/fundamentals/code-examples/linq.cs
:language: csharp
:dedent:
:start-after: start-ingredient-model
:end-before: end-ingredient-model

.. note:: Missing or Undefined Operands

If the operand list you pass to any bitwise operator contains a missing or
undefined value, the entire expression evaluates to ``null``.

$bitAnd
+++++++

The ``$bitAnd`` aggregation operator performs a bitwise AND operation on the given
arguments. You can use the ``$bitAnd`` operator by connecting two or more
clauses with a ``&`` character. The following example shows how to create a
``$bitAnd`` stage using LINQ:
mayaraman19 marked this conversation as resolved.
Show resolved Hide resolved

.. literalinclude:: /includes/fundamentals/code-examples/linq.cs
:language: csharp
:dedent:
:start-after: start-bitAnd-example
:end-before: end-bitAnd-example

The preceding example retrieves the document in which the ``Name`` field has the
value ``"eggs"``. It then performs a bitwise AND operation on the values of the
``Price`` and ``Count`` fields in this document, returning a value of ``4``.
mayaraman19 marked this conversation as resolved.
Show resolved Hide resolved

The following example performs the same bitwise AND operation, but on all
documents in the collection:
mayaraman19 marked this conversation as resolved.
Show resolved Hide resolved

.. io-code-block::
:copyable: true

.. input:: /includes/fundamentals/code-examples/linq.cs
:language: csharp
:dedent:
:start-after: start-bitAnd-collection-example
:end-before: end-bitAnd-collection-example

.. output::
:language: json
:visible: false

1
0
4
0
4
null

The ``null`` result comes from the document where the ``Name`` field
has the value of ``"cheese"``. This document is missing a ``Count`` field, so
the expression evaluates to ``null``.

$bitOr
++++++

The ``$bitOr`` aggregation operator performs a bitwise OR operation on the given
arguments. You can use the ``$bitOr`` operator by connecting two or more
clauses with a ``|`` character. The following example shows how to create a
``$bitOr`` stage using LINQ:

.. literalinclude:: /includes/fundamentals/code-examples/linq.cs
:language: csharp
:dedent:
:start-after: start-bitOr-example
:end-before: end-bitOr-example

The preceding example retrieves the document in which the ``Name`` field has the
value ``"eggs"``. It then performs a bitwise OR operation on the values of the
``Price`` and ``Count`` fields in this document, returning the value
``13``.

$bitNot
+++++++

The ``$bitNot`` aggregation operator performs a bitwise NOT operation on the given
argument. You can use the ``$bitNot`` operator by preceding an
operand with a ``~`` character. ``$bitNot`` only takes one argument. The
following example shows how to create a ``$bitNot`` stage using LINQ:

.. io-code-block::
:copyable: true

.. input:: /includes/fundamentals/code-examples/linq.cs
:language: csharp
:dedent:
:start-after: start-bitNot-example
:end-before: end-bitNot-example

.. output::
:language: json
:visible: false

-2
-5
-13
-5
-101
null

$bitXor
+++++++

The ``$bitXor`` aggregation operator performs a bitwise XOR operation on the given
arguments. You can use the ``$bitXor`` operator by connecting two or more
clauses with a ``^`` character. The following example shows how to create a
``$bitXor`` stage using LINQ:

.. literalinclude:: /includes/fundamentals/code-examples/linq.cs
:language: csharp
:dedent:
:start-after: start-bitXor-example
:end-before: end-bitXor-example

The preceding example retrieves the documents in which the ``Name`` field has
the value ``"eggs"`` or ``"watermelon"``. It then performs a bitwise XOR
operation on the values of the ``Price`` and ``Count`` fields in these
documents. The result contains the following values:

.. code-block:: json

4
9

Unsupported Aggregation Stages
------------------------------

Expand Down
55 changes: 54 additions & 1 deletion source/includes/fundamentals/code-examples/linq.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class Address
public string Building { get; set; }

[BsonElement("coord")]
public float[] Coordinates { get; set; }
public double[] Coordinates { get; set; }
mayaraman19 marked this conversation as resolved.
Show resolved Hide resolved

public string Street { get; set; }

Expand Down Expand Up @@ -63,3 +63,56 @@ public class Review
}

// end-review-model

// start-ingredient-model

public class Ingredient
{
public int Id { get; set; }

public string Name { get; set; }

public int Price { get; set; }

public int Count { get; set; }
}

// end-ingredient-model

// start-bitAnd-example

var query = queryableCollection
.Where(i => i.Name == "eggs")
.Select(i => i.Price & i.Count);

// end-bitAnd-example

// start-bitAnd-collection-example

var query = queryableCollection
.Select(i => i.Price & i.Count);

// end-bitAnd-collection-example

// start-bitOr-example

var query = queryableCollection
.Where(i => i.Name == "eggs")
.Select(i => i.Price | i.Count);

// end-bitOr-example

// start-bitNot-example

var queryable = collection
.Select(i => ~i.Count);

// end-bitNot-example

// start-bitXor-example

var query = queryableCollection
.Where(i => i.Name == "eggs" || i.Name == "watermelon")
.Select(i => i.Price ^ i.Count);

// end-bitXor-example
Loading