我正在尝试将Ayende的订单搜索从here应用到现有索引。
目前的指数如下:
public class HomeBlurb_IncludeTotalCosts_Search2 : AbstractIndexCreationTask<MPDocument, HomeBlurb_IncludeTotalCosts_Search2.ReduceResult>
{
public class ReduceResult
{
public string Name { get; set; }
public string Constituency { get; set; }
public decimal? AmountPaid { get; set; }
}
public HomeBlurb_IncludeTotalCosts_Search2()
{
Map = mps => from mp in mps
from exp in mp.Expenses
select new
{
mp.Name,
mp.Constituency,
exp.AmountPaid
};
Reduce = results => from result in results
group result by new { result.Name, result.Constituency } into g
select new
{
Name = g.Key.Name,
Constituency = g.Key.Constituency,
AmountPaid = g.Sum(x => x.AmountPaid)
};
Index(x => x.Name, FieldIndexing.Analyzed);
Index(x => x.Constituency, FieldIndexing.Analyzed);
}
}
此索引运行正常。但是当我尝试将Map更改为:
时from mp in mps
from exp in mp.Expenses
select new
{
Query = new object[]{mp.Name,mp.Constituency},
mp.Name,
mp.Constituency,
exp.AmountPaid
};
和reduce to
from result in results
group result by new { result.Name, result.Constituency } into g
select new
{
Query = "",
Name = g.Key.Name,
Constituency = g.Key.Constituency,
AmountPaid = g.Sum(x => x.AmountPaid)
};
在查询Query
属性时,我得不到任何结果。如果我删除了reduce,则索引返回数据,但它总是返回完整的MPDocument
,这比我实现的要多得多。有没有办法使用原始帖子中描述的技术,也使用减少?
答案 0 :(得分:1)
您可以在reduce函数中使用它:
Query = g.Select(x => x.Query).Where(x => x != null).FirstOrDefault()
要查询该字段,您需要具有单独的查询模型和结果模型。以下是使用您的代码的完整示例:
public class MultiTermFieldInMapReduce
{
public class MPDocument
{
public List<Epense> Expenses { get; set; }
public string Name { get; set; }
public string Constituency { get; set; }
public class Epense
{
public decimal? AmountPaid { get; set; }
}
}
public class HomeBlurb_IncludeTotalCosts_Search2 : AbstractIndexCreationTask<MPDocument, HomeBlurb_IncludeTotalCosts_Search2.ReduceResult>
{
public class ReduceResult
{
public string Name { get; set; }
public string Constituency { get; set; }
public decimal? AmountPaid { get; set; }
public object[] Query { get; set; }
}
public class SearchModel
{
public string Name { get; set; }
public string Constituency { get; set; }
public decimal? AmountPaid { get; set; }
public string Query { get; set; }
}
public HomeBlurb_IncludeTotalCosts_Search2()
{
Map = mps => from mp in mps
from exp in mp.Expenses
select new
{
mp.Name,
mp.Constituency,
exp.AmountPaid,
Query = new object[]
{
mp.Name,
mp.Constituency
}
};
Reduce = results => from result in results
group result by new { result.Name, result.Constituency } into g
select new
{
Name = g.Key.Name,
Constituency = g.Key.Constituency,
AmountPaid = g.Sum(x => x.AmountPaid),
Query = g.Select(x => x.Query).Where(x => x != null).FirstOrDefault()
};
Index(x => x.Name, FieldIndexing.Analyzed);
Index(x => x.Constituency, FieldIndexing.Analyzed);
}
}
[Fact]
public void Query_returns_results()
{
using (var store = new EmbeddableDocumentStore { RunInMemory = true }.Initialize())
{
using (var session = store.OpenSession())
{
session.Store(new MapReduceError.MPDocument
{
Name = "test1",
Expenses = new List<MapReduceError.MPDocument.Epense>
{
new MapReduceError.MPDocument.Epense {AmountPaid = 5.5m},
new MapReduceError.MPDocument.Epense {AmountPaid = 5.5m},
new MapReduceError.MPDocument.Epense {AmountPaid = 5.5m},
new MapReduceError.MPDocument.Epense {AmountPaid = 5.5m}
}
});
session.Store(new MapReduceError.MPDocument
{
Name = "test2",
Expenses = new List<MapReduceError.MPDocument.Epense>
{
new MapReduceError.MPDocument.Epense {AmountPaid = 10},
new MapReduceError.MPDocument.Epense {AmountPaid = 10},
new MapReduceError.MPDocument.Epense {AmountPaid = 10},
new MapReduceError.MPDocument.Epense {AmountPaid = 10}
}
});
session.SaveChanges();
}
new HomeBlurb_IncludeTotalCosts_Search2().Execute(store);
using (var session = store.OpenSession())
{
var results =
session.Query
<HomeBlurb_IncludeTotalCosts_Search2.SearchModel, HomeBlurb_IncludeTotalCosts_Search2>()
.Customize(x => x.WaitForNonStaleResultsAsOfLastWrite())
.Where(x => x.Query == "test1")
.As<HomeBlurb_IncludeTotalCosts_Search2.ReduceResult>()
.ToList();
Assert.Equal(1, results.Count);
Assert.Equal(22, results.First().AmountPaid);
}
}
}
}
答案 1 :(得分:0)
我认为你不需要Map / Reduce索引才能做到这一点,你似乎只是减少了MPDocument名称和选区,我认为每个MP都是独一无二的。
我认为您想要使用TransformResults,以便您可以改变输出的形状,如下所示:
TransformResults =
(database, mps) => from mp in mps
select new
{
mp.Name,
mp.???
< JUST THE BITS YOU WANT RETURNED >
};
然后你这样查询:
session.Query<mp>("index name")
.Where(..)
.As<MPQueryResult>()
.ToList()