获取所有集合的文档id的RavenDB以进行“按文档”修改

时间:2017-03-20 15:42:07

标签: python database ravendb nosql

我目前正在尝试在ravendb数据库中更新我的文档。问题是我有一个更新一个文档的方法,但它将doc作为参数。 我正在使用python,因此:pyravenDB作为接口。

方法如下:

def updateDocument(self,id,newAttribute)

        with self.store.open_session() as session:
            doc = session.load(id)
            doc.newAttribute= newAttribute
            session.save_changes()

我的想法是我将使用一个简单的for循环与目标集合的所有id并调用updateDocument方法。

我认为有一个updatebyindex方法,但我不知道如何使它适应我的用例。

我怎样才能获得这个?

谢谢!

2 个答案:

答案 0 :(得分:2)

我不是Python专家,但快速查看PyRavenDb的源代码,我可以找到store.database_commands中定义的database_commands.py

语法就像等效C# command

的语法
def update_by_index(self, index_name, query, scripted_patch=None, options=None):
    """
    @param index_name: name of an index to perform a query on
    :type str
    @param query: query that will be performed
    :type IndexQuery
    @param options: various operation options e.g. AllowStale or MaxOpsPerSec
    :type BulkOperationOptions
    @param scripted_patch: JavaScript patch that will be executed on query results( Used only when update)
    :type ScriptedPatchRequest
    @return: json
    :rtype: dict
    """
    if not isinstance(query, IndexQuery):
        raise ValueError("query must be IndexQuery Type")
    path = Utils.build_path(index_name, query, options)
    if scripted_patch:
        if not isinstance(scripted_patch, ScriptedPatchRequest):
            raise ValueError("scripted_patch must be ScriptedPatchRequest Type")
        scripted_patch = scripted_patch.to_json()

    response = self._requests_handler.http_request_handler(path, "EVAL", data=scripted_patch)
    if response.status_code != 200 and response.status_code != 202:
        raise response.raise_for_status()
    return response.json()

该函数接受索引名称查询,用于查找要更新的文档, JavaScript补丁这将修改文件'数据

如果您需要更新特定集合的所有文档,请考虑通过 Raven / DocumentsByEntityName 索引更新它们。它是一个系统索引,它自动创建并保存对整个数据库中所有文档的引用。因此,您可以编写查询,查找包含标记的所有文档,其值与您的集合名称相对应,例如Query = "Tag:Groups",并将查询传递给update_by_index方法。

您还可以通过batch命令完成文档更新,该命令也在database_commands.py中定义并记录在案here注意:仅当您知道文件的ID时才适用。

如果您对C#示例感兴趣,可以使用我去年在达拉斯参观RavenDB会议后创建的演示项目,https://github.com/maqduni/RavenDb-Demo

答案 1 :(得分:1)

像maqduni所说update_by_index是您想要使用的方法。 只需创建一个索引,索引您想要的文档。 如果你遇到麻烦,你可以尝试查询你想要的文件,然后ravendb将为你创建自动索引。创建索引后,只需使用update_by_indexindex_name调用query只是确保索引不陈旧

您的代码需要看起来像这样:

from pyravendb.data.indexes import IndexQuery
from pyravendb.data.patches import ScriptedPatchRequest
   self.store.database_commands.update_by_index(index_name="YOUR_INDEX_NAME",
        query=IndexQuery(query="TAG:collection_name;"),
        scripted_patch=ScriptedPatchRequest("this.Attribute = newAttribute;"))

IndexQuery中的查询是示例中的lucene语法索引中的TAG是我的所有集合名称。 scripted_patch是js语法,这是将在您查询的每个文档上运行的脚本。

我将尝试解释两者之间的差异:

get_index方法会为您提供有关响应为IndexDefinition的索引的信息。

update_by_index是一项长期任务操作,为什么你只需要等到operation_id才能完成。 (将在下一个pyravendb版本中为其创建一个功能)。 此操作不会为您提供修补的文档。新功能将为您提供有关该过程的信息。

page_size仅用于查询结果,不适用于索引操作