gpt4 book ai didi

mapreduce - RavenDb - 查询在 Reduce 函数中聚合的字段

转载 作者:行者123 更新时间:2023-12-05 01:15:41 25 4
gpt4 key购买 nike

我有一组代表一些工作项的文档:

public class WorkItem
{
public string Id {get;set;
public string DocumentId { get; set; }
public string FieldId { get; set; }
public bool IsValidated { get; set; }
}

public class ExtractionUser
{
public string Id {get;set;}
public string Name {get;set;}
public string[] AssignedFields {get;set;}
}

用户有权访问一组 FieldId。我需要根据这组字段查询 WorkItems 并获取每个文档的状态:

public class UserWorkItems
{
public string DocumentId { get; set; }
public int Validated { get; set; }
public int Total { get; set; }
}

我所追求的查询是这样的:

using (var session = RavenDb.OpenSession())
{
string[] userFields = session.Load<User>("users/1").Fields;
session.Query<WorkItem>()
.Where(w => w.FieldId.In(userFields))
.GroupBy(w => w.DocumentId)
.Select(g => new
{
DocumentId = g.Key,
Validated = g.Where(w => w.IsValidated).Count(),
Total = g.Count()
}).Skip(page * perPage).Take(perPage)
.ToArray();
}

我曾尝试创建 Map/Reduce 索引,但主要问题是我需要能够在 FieldId 上应用过滤器,该过滤器不包含在 Reduce 输出中,因为它是计数的属性。

我还尝试在 FieldId 上为查询部分和 TransformResults 做一个简单的 Map 索引来执行 GroupBy - 但是由于在 TransformResults 之前应用了分页,因此页面和总计反射(reflect)了分组之前的文档,这并不好。

然后我尝试使用多映射索引来映射用户及其字段集合,并映射工作项和字段,然后尝试将结果减少到我想要的。我创建了 a gist与索引定义。 reduce 部分涉及一个 group by 字段,然后是多个 SelectMany 以及最后的 GroupBy 和 Select。索引已被 raven 接受,但我没有返回任何结果。我有点卡在多 map 索引上,因为我不知道如何实际调试它。

我想最后我的问题可以减少(双关语)到如何查询“减少”的字段?

我有什么想法可以实现这样的功能吗?除了 Map/MultiMap/Reduce/TransformResults 之外,我还可以探索其他选项吗?

更新 : 阅读时 Ayende's Map Reduce post我意识到我正在接近 mapreduce 错误。仍在寻找解决方案...

更新 2 :经过更多的研究,我最终得到了这个索引,它看起来像我想要做的,但不返回任何数据(索引是直接在工作室中定义的):

map :

from user in docs
where user["@metadata"]["Raven-Entity-Name"] == "ExtractionUsers"
from field in user.AssignedFields
from item in docs
where item["@metadata"]["Raven-Entity-Name"] == "WorkItems" && item.FieldId == field
select new {
UserId = user.Id,
DocumentId = item.DocumentId,
Validated = item.Status=="Validated"? 1: 0,
Count = 1
}

降低:

from r in results
group r by new { r.UserId , r.DocumentId } into g
select new {
UserId = g.Key.UserId,
DocumentId = g.Key.DocumentId,
Validated = g.Sum(d => d.Validated),
Count = g.Sum(d => d.Count),
}

这个想法是尝试在索引中映射所有文档,并从用户链接到字段和工作项。

最佳答案

一周后,我设法解决了这个问题。我采用了一种稍微不同(较少相关)的方法,它很简单,而且似乎工作正常。以下是其他人遇到此类问题时的详细信息:

我按 DocumentId 对 WorkItems 进行分组,并将 Validated 和 NonValidated 字段放入一个集合中。 map 减少的结果如下所示:

public class Result
{
public string DocumentId { get; set; }
public string[] ValidatedFields { get; set; }
public string[] ReadyFields { get; set; }
}

map 函数看起来像这样:

Map = items => items.Select(i => new
{
DocumentId = i.DocumentId,
ValidatedFields = i.IsValidated ? new string[] { i.FieldId } : new string[0],
ReadyFields = !i.IsValidated ? new string[] { i.FieldId } : new string[0]
});

减少 :

Reduce = result => result
.GroupBy(i => i.DocumentId)
.Select(g => new
{
DocumentId = g.Key,
ValidatedFields = g.SelectMany(i => i.ValidatedFields),
ReadyFields = g.SelectMany(i => i.ReadyFields)
});

要查询索引,我现在使用以下表达式:

User user = session.Load<User>("users/1");
var result = session.Query<WorkItem, UserWorkItemIndex>()
.As<UserWorkItemIndex.Result>()
.Where(d => d.ValidatedFields.Any(f => f.In(user.AssignedFields)))
.ToArray();

我唯一需要在客户端做的就是只计算属于用户的字段。

还有一个 gist与解决方案。

关于mapreduce - RavenDb - 查询在 Reduce 函数中聚合的字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13249633/

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