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

  • 本文关键字:管道 分隔 获取 Wyam 文档 何根 wyam
  • 更新时间 :
  • 英文 :


>我有一个名为"Posts"的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. 从"帖子"中获取文档(我有一个文档集合)
  2. 选择Tags元值(现在我有一个字符串集合)
  3. 将其拆分为逗号(更大的字符串集合)
  4. 然后修剪和小写(仍然是字符串的集合)
  5. 消除重复数据(较小的字符串集合)
  6. 然后为列表中的每个值创建一个新文档,其中包含空正文和字符串的TagName值(我应该最终得到一个新文档的集合)

同样,这有效。 但是有更好的方法吗?

这实际上一点也不差 - 这里的部分挑战是将逗号分隔的标记列表转换为可由 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 } }))),
    // ...
);

请注意,我们仍然需要完成将逗号分隔的标签列表放入数组的工作 - 它只是在"Posts"管道的早期发生。

最新更新