def _copy_only_fields(self, doc, fields, container):
        """Copy only the specified fields."""

        if fields is None:
            return self._copy_field(doc, container)
        else:
            if not fields:
                fields = {"_id": 1}
            if not isinstance(fields, dict):
                fields = helpers._fields_list_to_dict(fields)

            # we can pass in something like {"_id":0, "field":1}, so pull the id
            # value out and hang on to it until later
            id_value = fields.pop('_id', 1)

            # filter out fields with projection operators, we will take care of them later
            projection_operators = self._extract_projection_operators(fields)

            # other than the _id field, all fields must be either includes or
            # excludes, this can evaluate to 0
            if len(set(list(fields.values()))) > 1:
                raise ValueError(
                    'You cannot currently mix including and excluding fields.')

            # if we have novalues passed in, make a doc_copy based on the
            # id_value
            if len(list(fields.values())) == 0:
                if id_value == 1:
                    doc_copy = container()
                else:
                    doc_copy = self._copy_field(doc, container)
            # if 1 was passed in as the field values, include those fields
            elif list(fields.values())[0] == 1:
                doc_copy = container()
                for key in fields:
                    key_parts = key.split('.')
                    subdocument = doc
                    subdocument_copy = doc_copy
                    full_key_path_found = True
                    for key_part in key_parts[:-1]:
                        if key_part not in subdocument:
                            full_key_path_found = False
                            break
                        subdocument = subdocument[key_part]
                        subdocument_copy = subdocument_copy.setdefault(key_part, {})
                    if not full_key_path_found or key_parts[-1] not in subdocument:
                        continue
                    subdocument_copy[key_parts[-1]] = subdocument[key_parts[-1]]
            # otherwise, exclude the fields passed in
            else:
                doc_copy = self._copy_field(doc, container)
                for key in fields:
                    key_parts = key.split('.')
                    subdocument_copy = doc_copy
                    full_key_path_found = True
                    for key_part in key_parts[:-1]:
                        if key_part not in subdocument_copy:
                            full_key_path_found = False
                            break
                        subdocument_copy = subdocument_copy[key_part]
                    if not full_key_path_found or key_parts[-1] not in subdocument_copy:
                        continue
                    del subdocument_copy[key_parts[-1]]

            # set the _id value if we requested it, otherwise remove it
            if id_value == 0:
                doc_copy.pop('_id', None)
            else:
                if '_id' in doc:
                    doc_copy['_id'] = doc['_id']

            fields['_id'] = id_value  # put _id back in fields

            # time to apply the projection operators and put back their fields
            self._apply_projection_operators(projection_operators, doc, doc_copy)
            for field, op in iteritems(projection_operators):
                fields[field] = op
            return doc_copy
dataset/ETHPy150Open vmalloc/mongomock/mongomock/collection.py/Collection._copy_only_fields/original