我想搜索属于用户(我附近)的东西。我定义了以下索引,但没有得到合并的结果集:
public class Things_ByLocation : AbstractMultiMapIndexCreationTask<Things_ByLocation.ThingsByLocationResult>
{
public class ThingsByLocationResult
{
public string ThingId { get; set; }
public string UserId { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public Things_ByLocation()
{
AddMap<Thing>(things => from t in things
select new
{
ThingId = t.Id,
UserId = (string)null,
Latitude = 0,
Longitude = 0,
_ = (object)null,
});
AddMap<User>(users => from u in users
select new
{
ThingId = (string)null,
UserId = u.Id,
Latitude = u.Latitude,
Longitude = u.Longitude,
_ = SpatialIndex.Generate(u.Latitude, u.Longitude)
});
Reduce = results => from result in results
group result by result.ThingId into g
let userId = g.Select(x => x.UserId).Where(t => !string.IsNullOrWhiteSpace(t)).FirstOrDefault()
let lat = g.Select(x => x.Latitude).Where(t => t != 0).FirstOrDefault()
let lng = g.Select(x => x.Longitude).Where(t => t != 0).FirstOrDefault()
select new
{
ThingId = g.Key,
UserId = userId,
Latitude = lat,
Longitude = lng,
_ = SpatialIndex.Generate(lat, lng)
};
Store(x => x.ThingId, FieldStorage.Yes);
Store(x => x.UserId, FieldStorage.Yes);
}
}
结果如下所示:
{
"ThingId": "Thing/Id26",
"UserId": null,
"Longitude": "0",
"__spatialShape": "0.000000 0.000000"
}
我的模型:
public class User
{
public string Id { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public class Thing
{
public string Id { get; set; }
public double Name { get; set; }
public double Description { get; set; }
public string UserId { get; set; }
}
关于我做错了什么的任何想法?如果我将组切换到用户,用户部分将被填充并且 ThingId 为空。因此,合并过程似乎失败了。我只是不确定为什么。
也很奇怪,为什么结果显示的是经度,而不是纬度属性。
在 RAM 中使用 RavenDB Build 960。
我意识到我可以将位置非规范化为事物,但这意味着如果用户位置发生变化,我可能必须更新数百个事物。这是首选的 NoSql 方法吗?
更新
根据 Ayende 的建议,我现在有以下内容:
public class Things_ByLocation : AbstractMultiMapIndexCreationTask<Things_ByLocation.ThingsByLocationResult>
{
public class ThingsByLocationResult
{
public string ThingId { get; set; }
public string UserId { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public Things_ByLocation()
{
AddMap<Thing>(things => from t in things
select new
{
ThingId = t.Id,
UserId = (string)null,
Latitude = 0,
Longitude = 0
});
AddMap<User>(users => from u in users
select new
{
ThingId = (string)null,
UserId = u.Id,
Latitude = u.Latitude,
Longitude = u.Longitude
});
Reduce = results => from result in results
group result by result.ThingId into g
select new
{
ThingId = g.Key,
UserId = g.Select(x => x.UserId).Where(x => x != null).FirstOrDefault(),
Latitude = g.Select(x => x.Latitude).Where(t => t != 0).FirstOrDefault(),
Longitude = g.Select(x => x.Longitude).Where(t => t != 0).FirstOrDefault()
};
Store(x => x.ThingId, FieldStorage.Yes);
Store(x => x.UserId, FieldStorage.Yes);
}
}
索引本身:
Map:
docs.Things
.Select(t => new {ThingId = t.__document_id, UserId = (String)null, Latitude = 0, Longitude = 0})
Map:
docs.Users
.Select(u => new {ThingId = (String)null, UserId = u.__document_id, Latitude = ((double)u.Latitude), Longitude = ((double)u.Longitude)})
Reduce:
results
.GroupBy(result => result.ThingId)
.Select(g => new {ThingId = g.Key, UserId = g
.Select(x => x.UserId)
.Where(x => x != null).FirstOrDefault(), Latitude = g
.Select(x => ((double)x.Latitude))
.Where(t => t != 0).FirstOrDefault(), Longitude = g
.Select(x => ((double)x.Longitude))
.Where(t => t != 0).FirstOrDefault()})
生成的投影如下所示:
{
"ThingId": "Thing/Id26",
"UserId": null,
"Latitude": null,
"Longitude": null
}
我似乎在这里做一些学术上的错误。