Scan this entire collection in parallel.

        Returns a list of up to ``num_cursors`` cursors that can be iterated
        concurrently. As long as the collection is not modified during
        scanning, each document appears once in one of the cursors result
        sets.

        For example, to process each document in a collection using some
        thread-safe ``process_document()`` function:

          >>> def process_cursor(cursor):
          ...     for document in cursor:
          ...     # Some thread-safe processing function:
          ...     process_document(document)
          >>>
          >>> # Get up to 4 cursors.
          ...
          >>> cursors = collection.parallel_scan(4)
          >>> threads = [
          ...     threading.Thread(target=process_cursor, args=(cursor,))
          ...     for cursor in cursors]
          >>>
          >>> for thread in threads:
          ...     thread.start()
          >>>
          >>> for thread in threads:
          ...     thread.join()
          >>>
          >>> # All documents have now been processed.

        The :meth:`parallel_scan` method obeys the :attr:`read_preference` of
        this :class:`Collection`.

        :Parameters:
          - `num_cursors`: the number of cursors to return
          - `**kwargs`: additional options for the parallelCollectionScan
            command can be passed as keyword arguments.

        .. note:: Requires server version **>= 2.5.5**.

        .. versionchanged:: 3.4
           Added back support for arbitrary keyword arguments. MongoDB 3.4
           adds support for maxTimeMS as an option to the
           parallelCollectionScan command.

        .. versionchanged:: 3.0
           Removed support for arbitrary keyword arguments, since
           the parallelCollectionScan command has no optional arguments.

def parallel_scan(self, num_cursors, **kwargs):
        """Scan this entire collection in parallel.

        Returns a list of up to ``num_cursors`` cursors that can be iterated
        concurrently. As long as the collection is not modified during
        scanning, each document appears once in one of the cursors result
        sets.

        For example, to process each document in a collection using some
        thread-safe ``process_document()`` function:

          >>> def process_cursor(cursor):
          ...     for document in cursor:
          ...     # Some thread-safe processing function:
          ...     process_document(document)
          >>>
          >>> # Get up to 4 cursors.
          ...
          >>> cursors = collection.parallel_scan(4)
          >>> threads = [
          ...     threading.Thread(target=process_cursor, args=(cursor,))
          ...     for cursor in cursors]
          >>>
          >>> for thread in threads:
          ...     thread.start()
          >>>
          >>> for thread in threads:
          ...     thread.join()
          >>>
          >>> # All documents have now been processed.

        The :meth:`parallel_scan` method obeys the :attr:`read_preference` of
        this :class:`Collection`.

        :Parameters:
          - `num_cursors`: the number of cursors to return
          - `**kwargs`: additional options for the parallelCollectionScan
            command can be passed as keyword arguments.

        .. note:: Requires server version **>= 2.5.5**.

        .. versionchanged:: 3.4
           Added back support for arbitrary keyword arguments. MongoDB 3.4
           adds support for maxTimeMS as an option to the
           parallelCollectionScan command.

        .. versionchanged:: 3.0
           Removed support for arbitrary keyword arguments, since
           the parallelCollectionScan command has no optional arguments.
        """
        cmd = SON([('parallelCollectionScan', self.__name),
                   ('numCursors', num_cursors)])
        cmd.update(kwargs)

        with self._socket_for_reads() as (sock_info, slave_ok):
            result = self._command(sock_info, cmd, slave_ok,
                                   read_concern=self.read_concern)

        return [CommandCursor(self, cursor['cursor'], sock_info.address)
                for cursor in result['cursors']]