如何根据以前管道中逗号分隔的元值获取Wyam文档管道?

时间:2016-01-28 10:53:57

标签: wyam

我有一个Wyam管道,名为"帖子"装满文件。其中一些文档具有Tags元值,这是一个以逗号分隔的标记列表。例如,我们假设它有三个文档,其中Tags元:

gumby,pokey
gumby,oscar
oscar,kermit

我希望在"帖子"中的所有文档中找到一个新的管道,其中包含一个文档,用于每个唯一标记。管道。这些文档应该在名为TagName的元值中包含标记。

因此,上述值应该会产生一个由四个文档组成的新管道,其中TagName元值为:

gumby
pokey
oscar
kermit

这是我的解决方案。 这在技术上有效,但我觉得它效率低下,而且我非常确定必须有更好的方法。

Documents(c => c.Documents["Posts"]
    .Select(d => d.String("Tags", string.Empty))
    .SelectMany(s => s.Split(",".ToCharArray()))
    .Select(s => s.Trim().ToLower())
    .Distinct()
    .Select(s => c.GetNewDocument(
        string.Empty,
        new List<KeyValuePair<string, object>>()
        {
            new KeyValuePair<string, object>("TagName", s)
        }
     ))
 )

所以,我正在调用Documents并传递ContextConfig

  1. 从&#34;帖子&#34;获取文件(我收集了一些文件)
  2. 选择Tags元值(现在我有一个字符串集合)
  3. 在逗号(更大的字符串集合)上拆分
  4. 然后修剪和小写(仍然是字符串的集合)
  5. 去掉它(一个较小的字符串集合)
  6. 然后为列表中的每个值创建一个新文档,其中包含空体和字符串的TagName值(我应该最终得到一组新文档)
  7. 再次,这是有效的。但是有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

这实际上并不坏 - 这里的部分挑战是将逗号分隔的标签列表转换为可由LINQ表达式或类似方法处理的内容。那部分可能是不可避免的,占你表达中的3行。

尽管如此,Wyam确实在ToLookup()扩展程序中提供了一些帮助(请参阅本页底部:http://wyam.io/getting-started/concepts)。

以下是它的外观(此代码来自一个独立的LINQPad脚本,需要进行调整才能在Wyam配置文件中使用):

public void Main()
{   
    Engine engine = new Engine();
    engine.Pipelines.Add("Posts",
        new PostsDocuments(),
        new Meta("TagArray", (doc, ctx) => doc.String("Tags")
            .ToLowerInvariant().Split(',').Select(x => x.Trim()).ToArray())
    );
    engine.Pipelines.Add("Tags",
        new Documents(ctx => ctx.Documents["Posts"]
            .ToLookup<string>("TagArray")
            .Select(x => ctx.GetNewDocument(new MetadataItems { { "TagName", x.Key } }))),
        new Execute((doc, ctx) =>
        {
            Console.WriteLine(doc["TagName"]);
            return null;
        })
    );
    engine.Execute();
}

public class PostsDocuments : IModule
{
    public IEnumerable<IDocument> Execute(IReadOnlyList<IDocument> inputs, IExecutionContext context)
    {
        yield return context.GetNewDocument(new MetadataItems { { "Tags", "gumby,pokey" } });
        yield return context.GetNewDocument(new MetadataItems { { "Tags", "gumby,oscar" } });
        yield return context.GetNewDocument(new MetadataItems { { "Tags", "oscar,kermit" } });
    }
}

输出:

gumby
pokey
oscar
kermit

很多只是用于设置假测试环境的内务处理。您正在寻找的重要部分是:

engine.Pipelines.Add("Tags",
    new Documents(ctx => ctx.Documents["Posts"]
        .ToLookup<string>("TagArray")
        .Select(x => ctx.GetNewDocument(new MetadataItems { { "TagName", x.Key } }))),
    // ...
);

请注意,我们仍然需要将逗号分隔标记列表添加到数组中 - 它只是在早期发生在&#34;帖子&#34;管道