我正在使用Couchbase v4.5和.NET SDK 2.3.8版。我正在将视图迁移到N1QL查询。视图可用的Javascirpt为我提供了对文档数组成员进行排序的灵活性,并随后从数组中选择了一个元素。所以在我看来,我有:
'Username': doc.Document.LogActions.sort(function(a,b){ return (a.Time > b.Time) })[doc.Document.LogActions.length - 1].Username
...我现在正努力通过N1QL查询中的.NET SDK来完成相同的工作。需要注意的是,我试图仅在LINQ中执行此操作。我意识到我可以使用原始字符串查询,它提供完整的N1QL支持,但团队负责人希望通过LINQ完成此操作......除非通过LINQ完全无法做到这一点。
我尝试过以下方法:
排序 - 不允许按数组中对象的属性排序
Username = doc.Document.LogActions
.OrderByDescending(logAction => logAction.Time)
.FirstOrDefault()
.Username,
刚刚过去 - 最后不支持
Username = transaction.Document.LogActions
.LastOrDefault()
.Username,
无排序 - 仍会返回数组
Username = transaction.Document
.LogActions[transaction.Document.LogActions.Count - 1]
.Username
我能想到的另一件事就是将数组返回给.NET并在那里进行过滤。但是,我们没有关于平均数量中有多少项的基线。我们宁愿避免带回我们不需要的数据。
我是否已经降级为使用原始字符串查询?理想情况下,我试图找到最新的"日志操作"来自数组,基于Time
属性。
答案 0 :(得分:1)
我用这个玩了一些,虽然看起来像这样的东西应该有效:
Username = transaction.Document.LogActions
.OrderByDescending(logAction => logAction.Time)
.Select(g => g.Username)
.ToArray()[0],
......唉,事实并非如此。我收到“N1Ql数组子查询支持仅按数组元素排序”的错误。所以我尝试使用GroupBy
- 为咯咯笑 - 而且看到我确实得到了结果:
Username = transaction.Document.LogActions
.OrderByDescending(logAction => logAction.Time)
.GroupBy(logAction => new { logAction.Time, logAction.Username })
.Select(g => g.Key.Username)
.ToArray()[0],
这让我确认我得到正确的结果 - 因为CB的排序看起来有点不稳定 - 但它至少是半工作的。
答案 1 :(得分:0)
我不是LINQ的专家。但以下是N1QL查询。
MAX,MIN参数允许数组。数组的第0个元素可以是字段需要聚合,第1个元素是你想要携带的。使用此技术,您可以为MIN / MAX投影非聚合字段,如下所示。
INSERT INTO default VALUES ("k01",{ "logActions":[ { "User":"u1", "Time":"2017-11-52T14:35:00Z" }, { "User":"u2", "Time":"2017-11-09T14:35:00Z" }, { "User":"u3", "Time":"2017-11-03T14:35:00Z" }, { "User":"u4", "Time":"2017-11-02T14:35:00Z" }, ] });
SELECT MAX([u.Time,u.User])[1] AS User FROM default d USE KEYS "k01" UNNEST d.logActions AS a;
同时结帐N1QL : Find latest status from an array
在5.0.0中使用N1QL子查询表达式可以实现此https://developer.couchbase.com/documentation/server/current/n1ql/n1ql-language-reference/subqueries.html。