【问题标题】:Mongoengine - How to perform a "save new item or increment counter" operation?Mongoengine - 如何执行“保存新项目或增加计数器”操作?
【发布时间】:2013-01-31 10:21:21
【问题描述】:

我在一个网络抓取项目中使用 MongoEngine。我想跟踪我在所有抓取的网页上遇到的所有图像。

为此,我存储了图片src URL 和图片出现的次数。

MongoEngine 模型定义如下:

class ImagesUrl(Document):
    """ Model representing images encountered during web-scraping.

    When an image is encountered on a web-page during scraping,
    we store its url and the number of times it has been
    seen (default counter value is 1).
    If the image had been seen before, we do not insert a new document
    in collection, but merely increment the corresponding counter value.

    """

    # The url of the image. There cannot be any duplicate.
    src = URLField(required=True, unique=True)

    # counter of the total number of occurences of the image during
    # the datamining process
    counter = IntField(min_value=0, required=True, default=1)

我正在寻找实现“保存或递增”过程的正确方法。

到目前为止,我都是这样处理的,但我觉得 MongoEngine 可能有更好的内置方式:

def save_or_increment(self):
    """ If it is the first time the image has been encountered, insert
        its src in mongo, along with a counter=1 value.
        If not, increment its counter value by 1.

    """ 
    # check if item is already stored
    # if not, save a new item
    if not ImagesUrl.objects(src=self.src):
        ImagesUrl(
            src=self.src,
            counter=self.counter,
            ).save()
    else:
        # if item already stored in Mongo, just increment its counter
        ImagesUrl.objects(src=self.src).update_one(inc__counter=1)

有没有更好的方法?

非常感谢您的宝贵时间。

【问题讨论】:

    标签: python mongodb mongoengine


    【解决方案1】:

    你应该可以只做一个upsert 例如:

     ImagesUrl.objects(src=self.src).update_one(
                                      upsert=True, 
                                      inc__counter=1, 
                                      set__src=self.src)
    

    【讨论】:

    • 顺便问一下,您建议用这种行为覆盖 Document.save() 函数,还是在新的 ImagesUrl 方法中实现它?
    • 我建议你不要使用save,因为它的意图不是很清楚——我只需要使用update_one 代码。
    【解决方案2】:

    update_one 如@ross 答案中的结果是修改文档的计数(或更新的完整结果),它不会返回文档或新的计数器编号。如果你想拥有一个,你应该使用upsert_one

    images_url = ImagesUrl.objects(src=self.src).upsert_one(
                                                  inc__counter=1,
                                                  set__src=self.src)
    print images_url.counter
    

    如果文档不存在则创建文档或修改文档并增加计数器数量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-17
      • 1970-01-01
      • 2016-01-05
      • 2018-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多