添加或更新列表中的引用字段

时间:2014-07-30 11:20:33

标签: python mongodb mongoengine

在我的数据模型中,Layer会保留其他相关图层的列表。我希望能够按相应的分数对相关图层进行排序,因此linked字段指的是保留分数的Link类以及对其他图层的引用:

class Layer(Document):
    name = StringField()
    linked = ListField(ReferenceField('Link'))

class Link(Document):
    doc = ReferenceField('Layer')
    modified = DateTimeField()
    score = LongField()

如何添加或更新Link?我想做点什么:

def add_link(layer1, layer2):
    if layer2 in layer1.linked:
        link = layer1.linked[layer2]
        link.score += 1
        link.modified = now()
        link.save()
    else:
        link = Link()
        link.score = 1
        link.modified = now()
        link.save()

1 个答案:

答案 0 :(得分:0)

我真正拥有的是多对多的关系。我通过删除Layer.linked字段并在更新链接时使用update(upsert=True)解决了这个问题:

class Layer(Document):
    name = StringField()

class Link(Document):
    layer1 = ReferenceField('Layer')
    layer2 = ReferenceField('Layer')
    modified = DateTimeField()
    score = LongField()

def add_link(layer1, layer2):
    # Refer to layers in a consistent (but arbitrary) order
    if layer1.id < layer2.id:
        a = layer1
        b = layer2
    else:
        a = layer2
        b = layer1
    # Create or update
    Link.objects(layer1=a, layer2=b).update_one(
        set__modified=datetime.datetime.utcnow(),
        inc__score=1,
        upsert=True)

如果在链接尚未存在的同时运行两个更新,则显然upsert can cause trouble。完整的解决方案可能需要在layer1layer2字段上uniquecompound index,并在add_link中进行错误检查,以防创建失败。