在 RavenDB 中,我有一组针对不同10种或更多语言的网页PageTextElement。翻译者应该能够看到基本语言,如英语,将其与其他语言进行比较,例如瑞典语,这样他就可以轻松更新文本或插入翻译(如果缺少) 。对我来说,它听起来像是一个简单的自我左连接。我现在明白RavenDB没有support join out of the box. You have to use a map reduce index。我想我几乎可以开始工作了。
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
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可以找到更丰富的代码: 或者我的LeftJoin experiment project at github:实际上我的地图中的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"
}
答案 0 :(得分: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)
};
}
}
其中给出了以下输出: