2

RavenDB 中,我收集了 10 种或更多不同语言的网页 PageTextElement。翻译人员应该能够看到像英语这样的基本语言,并将其与另一种语言(如瑞典语)进行比较,这样他就可以轻松地更新文本或在缺少翻译时插入翻译。对我来说,这听起来像是一个简单的 self left join。我现在了解到 RavenDB 不支持开箱即用的联接。您必须使用 map reduce index。我想我几乎让它工作了。

我可以在 RavenDB 中表达一个 self left join 和 group by:

SELECT bt.Page,bt.Token,bt.Webtext AS baseText,COUNT(ct.Webtext) 
FROM dbo.PageTextElement_TB bt
LEFT JOIN dbo.PageTextElement_TB AS ct 
    ON bt.Page=ct.Page 
    AND bt.Token = ct.Token 
    AND ct.Language='sv' 
WHERE bt.Language='en'
GROUP BY bt.Page,bt.Token,bt.Webtext

我能做的结果

|Page       |Token              |baseText                                       |count
--------------------------------------------------------------------------------------
|home       |PriceModel         |Based on weight and oxygen consumption         |1
|home       |RebateModel        |Truly Unique talent can reduce price with 50%  |0
|home       |RulesOfBoarding    |Do not break line                              |1  
|home       |Welcome            |Welcome to Aniara                              |1

但我想表达 RavenDB 中两个连接集合的字段:

SELECT bt.Page,bt.Token,bt.Webtext AS baseText,ct.Webtext AS compareText 
FROM dbo.PageTextElement_TB bt
LEFT JOIN dbo.PageTextElement_TB AS ct 
    ON bt.Page=ct.Page 
    AND bt.Token = ct.Token 
    AND ct.Language='sv' 
WHERE bt.Language='en'

我想要的结果表

|Page       |Token              |baseText                         |compareText
--------------------------------------------------------------------------------------
|home       |PriceModel         |Based on weight and oxygen consumption |Priset baseras på vikt och syreförbrukning
|home       |RebateModel        |Truly Unique talent can reduce price with 50%  |NULL
|home       |RulesOfBoarding    |Do not break line     |Träng dig ej i kön
|home       |Welcome            |Welcome to Aniara     |Välkommen till Aniara

这是我的地图减少索引,几乎可以满足我的要求。

 public class LeftJoinPageTextTranslationsCount : AbstractMultiMapIndexCreationTask<ComparePageTextElementCount>
        {
            public LeftJoinPageTextTranslationsCount()
            {
                AddMap<PageTextElement>(baseElements => 
                    from baseElement in baseElements.Where(l => l.Language == "en")
                    select new { Page = baseElement.Page, Token = baseElement.Token, baseElement.Webtext,WebtextCompare=(string)null, Count = 0 });

                AddMap<PageTextElement>(compareElements => 
                    from compareElement in compareElements.Where(l => l.Language == "sv")
                    select new { Page = compareElement.Page, Token = compareElement.Token, Webtext = (string)null,WebtextCompare=compareElement.Webtext, Count = 1 }
                    );
                Reduce = results => from result in results
                                    group result by
                                        new{Page = result.Page,Token = result.Token}
                                        into g
                                        select new
                                        {
                                            Page = g.Select(x => x.Page).Where(x => x != null).First(),
                                            Token = g.Select(x => x.Token).Where(x => x != null).First(),
                                            Webtext = g.Select(x => x.Webtext).Where(x => x != null).First(),
                                            WebtextCompare=g.Select(x => x.Webtext).Where(x => x != null).Last(),
                                            Count = g.Sum( x => x.Count)
                                        };
                Index(x => x.Webtext, FieldIndexing.Analyzed);
            }
        }

地图减少索引的结果

{
  "Page": "home",
  "Token": "PriceModel",
  "Webtext": "Based on weight and oxygen consumption",
  "WebtextCompare": "Based on weight and oxygen consumption",
  "Count": "1"
}
{
  "Page": "home",
  "Token": "RebateModel",
  "Webtext": "Truly Unique talent can reduce price with 50% ",
  "WebtextCompare": "Truly Unique talent can reduce price with 50% ",
  "Count": "0"
}
{
  "Page": "home",
  "Token": "Welcome",
  "Webtext": "Welcome to Aniara",
  "WebtextCompare": "Welcome to Aniara",
  "Count": "1"
}
{
  "Page": "home",
  "Token": "RulesOfBoarding",
  "Webtext": "Do not break line",
  "WebtextCompare": "Do not break line",
  "Count": "1"
}

我的问题是

为什么英文文本出现在瑞典文本应该出现的位置?

不幸的是,WebtextCompare 字段显示的是英文而不是瑞典文。更丰富的代码可以在我的gist中找到:或者我在 github 上的 LeftJoin 实验项目:实际上我的 map reduce index 中的 Count 不是必需的,它是我想要其他语言的 WebTextCompare 字段(本例中为瑞典语)。

我想要的地图减少索引的结果

{
  "Page": "home",
  "Token": "PriceModel",
  "Webtext": "Based on weight and oxygen consumption",
  "WebtextCompare": "Priset baseras på vikt och syreförbrukning",
  "Count": "1"
}
{
  "Page": "home",
  "Token": "RebateModel",
  "Webtext": "Truly Unique talent can reduce price with 50% ",
  "WebtextCompare": NULL,
  "Count": "0"
}
{
  "Page": "home",
  "Token": "Welcome",
  "Webtext": "Welcome to Aniara",
  "WebtextCompare": "Välkommen till Aniara",
  "Count": "1"
}
{
  "Page": "home",
  "Token": "RulesOfBoarding",
  "Webtext": "Do not break line",
  "WebtextCompare": "Träng dig ej i kön",
  "Count": "1"
}
4

1 回答 1

2

好吧,这里似乎发生了一些事情。

a) 你遇到这么多麻烦的原因在这里:

Webtext = g.Select(x => x.Webtext).Where(x => x != null).First(),
WebtextCompare=g.Select(x => x.Webtext).Where(x => x != null).Last(),

注意第二行,那里有Webtext。而不是 WebtextCompare。

此外,您不应在索引中使用 First 或 Last,而应使用 FirstOrDefault 或 LastOrDefault。

这是您想要的完整索引定义:

public class LeftJoinPageTextTranslationsCount : AbstractMultiMapIndexCreationTask<ComparePageTextElementCount>
{
    public LeftJoinPageTextTranslationsCount()
    {
        AddMap<PageTextElement>(baseElements =>
                                from baseElement in baseElements.Where(l => l.Language == "en")
                                select
                                    new
                                        {
                                            baseElement.Page,
                                            baseElement.Token,
                                            baseElement.Webtext,
                                            WebtextCompare = (string) null,
                                            Count = 0
                                        });

        AddMap<PageTextElement>(compareElements =>
                                from compareElement in compareElements.Where(l => l.Language == "sv")
                                select
                                    new
                                        {
                                            compareElement.Page,
                                            compareElement.Token,
                                            Webtext = (string) null,
                                            WebtextCompare = compareElement.Webtext,
                                            Count = 1
                                        }
            );
        Reduce = results => from result in results
                            group result by
                                new { result.Page, result.Token }
                                into g
                                select new
                                    {
                                        g.Key.Page,
                                        g.Key.Token,
                                        Webtext = g.Select(x => x.Webtext).FirstOrDefault(x => x != null),
                                        WebtextCompare = g.Select(x => x.WebtextCompare).FirstOrDefault(x => x != null),
                                        Count = g.Sum(x => x.Count)
                                    };
        Index(x => x.Webtext, FieldIndexing.Analyzed);
    }
}

这是输出:

正确的结果

B) LeftJoinProject 可以使用以下索引处理:

public class LeftJoinIndex : AbstractMultiMapIndexCreationTask<LeftJoinIndex.ReduceResult>
{
    public class ReduceResult
    {
        public string TeacherName;
        public string[] Students;
    }
    public LeftJoinIndex()
    {
        AddMap<Students>(studentsList =>
                        from list in studentsList
                        from student in list.List
                        select new
                            {
                                TeacherName = student.HomeRoomTeacher,
                                Students = new[] { student.Name }
                            }
            );

        AddMap<Teachers>(teacherLists =>
                        from list in teacherLists
                        from teacher in list.List
                        select new
                            {
                                TeacherName = teacher.Name,
                                Students = new string[0]
                            }
        );

        Reduce = results =>
                 from reduceResult in results
                 group reduceResult by reduceResult.TeacherName
                     into g
                     select new
                         {
                             TeacherName = g.Key,
                             Students = g.SelectMany(x => x.Students)
                         };
    }
}

这给出了以下输出:

LeftJoinIndex 输出

于 2013-09-23T07:25:35.717 回答