gpt4 book ai didi

azure - 在 DocumentDb Select 中形状不正确

转载 作者:行者123 更新时间:2023-12-03 04:32:15 25 4
gpt4 key购买 nike

我试图在 SELECT 查询中仅获取此人的成员资格信息,即 ID、姓名和委员会成员资格。这是我的目标:

{
"id": 123,
"name": "John Smith",
"memberships": [
{
"id": 789,
"name": "U.S. Congress",
"yearElected": 2012,
"state": "California",
"committees": [
{
"id": 444,
"name": "Appropriations Comittee",
"position": "Member"
},
{
"id": 555,
"name": "Armed Services Comittee",
"position": "Chairman"
},
{
"id": 678,
"name": "Veterans' Affairs Comittee",
"position": "Member"
}
]
}
]
}

在此示例中,John Smith 是美国国会及其三个委员会的成员。

我想要得到的结果应该是这样的。再说一遍,这是“期望的结果”:

{
"id": 789,
"name": "U.S. Congress",
"committees": [
{
"id": 444,
"name": "Appropriations Committee",
"position": "Member"
},
{
"id": 555,
"name": "Armed Services Committee",
"position": "Chairman"
},
{
"id": 678,
"name": "Veterans' Affairs Committee",
"position": "Member"
}
]
}

这是我的 SQL 查询:

SELECT m.id, m.name, 
[
{
"id": c.id,
"name": c.name,
"position": c.position
}
] AS committees
FROM a
JOIN m IN a.memberships
JOIN c IN m.committees
WHERE a.id = "123"

我得到以下结果,这是正确的,但形状不正确。我获得相同的成员(member)资格 3 次。这是我得到的结果,这不是想要的结果:

[
{
"id": 789,
"name": "U.S. Congress",
"committees":[
{
"id": 444,
"name": "Appropriations Committee",
"position": "Member"
}
]
},
{
"id": 789,
"name": "U.S. Congress",
"committees":[
{
"id": 555,
"name": "Armed Services Committee",
"position": "Chairman"
}
]
},
{
"id": 789,
"name": "U.S. Congress",
"committees":[
{
"id": 678,
"name": "Veterans' Affairs Committee",
"position": "Member"
}
]
}
]

正如您在此处看到的,“美国国会”成员资格重复了 3 次。

以下 SQL 查询在 Azure 查询资源管理器中准确地提供了我想要的内容,但是当我使用 DocumentDb SDK 将其作为查询传递到代码中时,我没有获得委员会的任何详细信息。我只是得到委员会 ID、姓名和职位的空白结果。不过,我确实获取了成员(member)数据,即“美国国会”等。这是 SQL 查询:

SELECT m.id, m.name, m.committees AS committees 
FROM c
JOIN m IN c.memberhips
WHERE c.id = 123

我包含了进行 DocumentDb 调用的代码。我将代码包含在我们的内部注释中,以帮助阐明其目的:

首先是 ReadQuery 函数,每当我们需要从 DocumentDb 读取内容时我们都会调用该函数:

public async Task<IEnumerable<T>> ReadQuery<T>(string collectionId, string sql, Dictionary<string, object> parameterNameValueCollection)
{
// Prepare collection self link
var collectionLink = UriFactory.CreateDocumentCollectionUri(_dbName, collectionId);

// Prepare query
var query = getQuery(sql, parameterNameValueCollection);

// Creates the query and returns IQueryable object that will be executed by the calling function
var result = _client.CreateDocumentQuery<T>(collectionLink, query, null);

return await result.QueryAsync();
}

以下函数使用任何参数准备查询:

protected SqlQuerySpec getQuery(string sql, Dictionary<string, object> parameterNameValueCollection)
{
// Declare query object
SqlQuerySpec query = new SqlQuerySpec();

// Set query text
query.QueryText = sql;

// Convert parameters received in a collection to DocumentDb paramters
if (parameterNameValueCollection != null && parameterNameValueCollection.Count > 0)
{
// Go through each item in the parameters collection and process it
foreach (var item in parameterNameValueCollection)
{
query.Parameters.Add(new SqlParameter($"@{item.Key}", item.Value));
}
}

return query;
}

此函数对 DocumentDb 进行异步调用:

public async static Task<IEnumerable<T>> QueryAsync<T>(this IQueryable<T> query)
{
var docQuery = query.AsDocumentQuery();

// Batches gives us the ability to read data in chunks in an asyc fashion.
// If we use the ToList<T>() LINQ method to read ALL the data, the call will synchronous which is why we prefer the batches approach.
var batches = new List<IEnumerable<T>>();

do
{
// Actual call is made to the backend DocumentDb database
var batch = await docQuery.ExecuteNextAsync<T>();
batches.Add(batch);
}

while (docQuery.HasMoreResults);

// Because batches are collections of collections, we use the following line to merge all into a single collection.
var docs = batches.SelectMany(b => b);

// Return data
return docs;
}

最佳答案

我只是编写了一个演示来测试您的查询,我可以获得预期的结果,请查看下面的快照。所以我认为该查询是正确的,您提到在我的代码中进行调用时似乎没有获取任何数据,您介意分享您的代码吗?也许您的代码中有一些错误。不管怎样,这是我的测试,仅供您引用,希望对您有所帮助。

enter image description here

使用的查询:

SELECT m.id AS membershipId, m.name AS membershipNameName, m.committees AS committees 
FROM c
JOIN m IN c.memberships
WHERE c.id = "123"

这里的代码非常简单,sp_db.innerText代表一个范围,我用它来在我的测试页面中显示结果:

var docs = client.CreateDocumentQuery("dbs/" + databaseId + "/colls/" + collectionId,
"SELECT m.id AS membershipId, m.name AS membershipName, m.committees AS committees " +
"FROM c " +
"JOIN m IN c.memberships " +
"WHERE c.id = \"123\"");
foreach (var doc in docs)
{
sp_db.InnerText += doc;
}

我认为您在client.CreateDocumentQuery()中指定的查询中可能存在一些拼写错误,导致结果为none,最好为我们提供代码,然后我们可以帮助检查它。

更新:
刚刚尝试了你的代码,我仍然可以获得预期的结果。我发现的一件事是,当我指定像 "where c.id =\"123\"" 这样的 where 子句时,它会得到结果: enter image description here

但是,如果您没有进行转义,而只是使用“where c.id = 123”,那么这次您什么也得不到。我想这可能是一个原因。您可以验证一下您是否遇到过这种情况。
enter image description here

关于azure - 在 DocumentDb Select 中形状不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35108359/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com