class_docstr: TaskManager
  
  Here is what will a task looks like when it created by TaskManager
  
  .. code-block:: python
  
      {
          'def': pickle serialized task definition.  using pickle will make it easier
          'filter': json-like data. This is for filtering the tasks.
          'status': 'waiting' | 'running' | 'done'
          'res': pickle serialized task result,
      }
  
  The tasks manager assumes that you will only update the tasks you fetched.
  The mongo fetch one and update will make it date updating secure.
  
  This class can be used as a tool from commandline. Here are several examples.
  You can view the help of manage module with the following commands:
  python -m qlib.workflow.task.manage -h # show manual of manage module CLI
  python -m qlib.workflow.task.manage wait -h # show manual of the wait command of manage
  
  .. code-block:: shell
  
      python -m qlib.workflow.task.manage -t <pool_name> wait
      python -m qlib.workflow.task.manage -t <pool_name> task_stat
  
  
  .. note::
  
      Assumption: the data in MongoDB was encoded and the data out of MongoDB was decoded
  
  Here are four status which are:
  
      STATUS_WAITING: waiting for training
  
      STATUS_RUNNING: training
  
      STATUS_PART_DONE: finished some step and waiting for next step
  
      STATUS_DONE: all work done
docstr: Query task in collection.
  This function may raise exception `pymongo.errors.CursorNotFound: cursor id not found` if it takes too long to iterate the generator
  
  python -m qlib.workflow.task.manage -t <your task pool> query '{"_id": "615498be837d0053acbc5d58"}'
  
  Parameters
  ----------
  query: dict
      the dict of query
  decode: bool
  
  Returns
  -------
  dict: a task(document in collection) after decoding
docstr_tok: ["Query","task","in","collection",".","This","function","may","raise","exception","`","pymongo.errors.CursorNotFound",":","cursor","id","not","found","`","if","it","takes","too","long","to","iterate","the","generator","python","-m","qlib.workflow.task.manage","-t","<","your","task","pool",">","query","'","{","``","_id","''",":","``","615498be837d0053acbc5d58","''","}","'","Parameters","--","--","--","--","--","query",":","dict","the","dict","of","query","decode",":","bool","Returns","--","--","--","-","dict",":","a","task","(","document","in","collection",")","after","decoding"]
code: def query(self, query={}, decode=True):
      """
      Query task in collection.
      This function may raise exception `pymongo.errors.CursorNotFound: cursor id not found` if it takes too long to iterate the generator
  
      python -m qlib.workflow.task.manage -t <your task pool> query '{"_id": "615498be837d0053acbc5d58"}'
  
      Parameters
      ----------
      query: dict
          the dict of query
      decode: bool
  
      Returns
      -------
      dict: a task(document in collection) after decoding
      """
      query = query.copy()
      query = self._decode_query(query)
      for t in self.task_pool.find(query):
          yield self._decode_task(t)
  
imports: import concurrent
  import pickle
  import time
  from contextlib import contextmanager
  from typing import Callable, List
  import fire
  import pymongo
  from bson.binary import Binary
  from bson.objectid import ObjectId
  from pymongo.errors import InvalidDocument
  from qlib import auto_init, get_module_logger
  from tqdm.cli import tqdm
  from .utils import get_mongodb
  from ...config import C
label_desc: Use image node_id 14 for calling the TaskManager obj's underlying member method code with example usage: obj.query(query, decode) without return types