1

我尝试了许多不同的策略来索引我的数据,但我自己似乎无法弄清楚。

我正在建立一个关于用户及其游戏的数据库。用户可以向数据库提供他们拥有并想要交易的游戏以及他们想要拥有的游戏列表:

public class Member : EntityBase
{
    public List<Game> TradeList { get; set; }
    public List<Game> WishList { get; set; }
}

我正在尝试创建和索引我可以以“给我一个列表,列出所有游戏(以及相应的成员),这些游戏的 TradeList 中的游戏与我的 WishList 匹配,以及他们的 WishList 中的游戏与我的 TradeList 匹配”。 .当然,我自己排除在外。

我尝试创建一个 MultiMapIndex:

public class TradingIndex : AbstractMultiMapIndexCreationTask<TradingIndex.Result>
{
    public enum ListType
    {
        Wishlist,
        Tradelist
    }

    public class Result
    {
        public string Game { get; set; }
        public string Member { get; set; }
        public ListType List { get; set; }
    }

    public TradingIndex()
    {
        AddMap<Member>(members => from member in members
            from game in member.TradeList
            select new Result()
            {
                Game = game.Id,
                Member = member.Id,
                List = ListType.Tradelist
            });

        AddMap<Member>(members => from member in members
            from game in member.WishList
            select new Result()
            {
                Game = game.Id,
                Member = member.Id,
                List = ListType.Wishlist
            });
    }
}

然后像这样查询它:

db.Query<TradingIndex.Result, TradingIndex>()
    .Where(g => 
        (g.Game.In(gamesIWant) && g.List == TradingIndex.ListType.Tradelist)
        &&
        (g.Game.In(gamesITrade) && g.List == TradingIndex.ListType.Wishlist)
        &&
        g.Member != me.Id
)

但我无法让它发挥作用。我也看过 Map/Reduce,但我的问题似乎是让 RavenDB 给我正确的结果类型。

我希望你能得到我想要做的事情,并且能给我一些关于要研究什么的提示。

4

1 回答 1

1

首先,您需要确保存储要编制索引的字段。这是必需的,因此您可以获取索引结果,而不是与索引匹配的文档

将此添加到索引定义的底部:

StoreAllFields(FieldStorage.Yes);

或者,如果您想更详细一些,(也许您的索引也在做其他事情):

Store(x => x.Game, FieldStorage.Yes);
Store(x => x.Member, FieldStorage.Yes);
Store(x => x.List, FieldStorage.Yes);

当你查询这个时,你需要告诉 Raven 将索引条目发回给你,使用ProjectFromIndexFieldsInto 这里描述的方法。

接下来,您需要意识到您没有创建任何与您的查询匹配的单个索引条目。多地图索引在索引中为每个地图创建单独的条目。如果要将它们组合到结果中,则需要使用交集查询

综上所述,您的查询应如下所示:

var q = session.Query<TradingIndex.Result, TradingIndex>()
               .Where(g => g.Game.In(gamesIWant) && 
                           g.List == TradingIndex.ListType.Tradelist &&
                           g.Member != me.Id)
               .Intersect()
               .Where(g => g.Game.In(gamesITrade) &&
                           g.List == TradingIndex.ListType.Wishlist &&
                           g.Member != me.Id)
               .ProjectFromIndexFieldsInto<TradingIndex.Result>();

此 GIST 中的完整测试

于 2013-11-02T22:08:26.417 回答