Mapreduce RavenDB中带空间索引的多地图索引失败
我想搜索属于用户的东西(在我附近)。我已定义了以下索引,但未获得合并结果集:Mapreduce RavenDB中带空间索引的多地图索引失败,mapreduce,ravendb,Mapreduce,Ravendb,我想搜索属于用户的东西(在我附近)。我已定义了以下索引,但未获得合并结果集: public class Things_ByLocation : AbstractMultiMapIndexCreationTask<Things_ByLocation.ThingsByLocationResult> { public class ThingsByLocationResult { public string ThingId { get; set; }
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);
}
}
我的模型:
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; }
}
你知道我做错了什么吗?如果我将组切换到用户,则会填充user部分,ThingId为null。因此,合并过程似乎失败了。我只是不知道为什么
这也很奇怪,为什么结果显示的是经度,而不是纬度属性
在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);
}
}
生成的投影如下所示:
{
"ThingId": "Thing/Id26",
"UserId": null,
"Longitude": "0",
"__spatialShape": "0.000000 0.000000"
}
{
"ThingId": "Thing/Id26",
"UserId": null,
"Latitude": null,
"Longitude": null
}
我在这里似乎做了一些学术上的错误。试试:
- 从地图中删除SpatialIndex.Generate时,它应仅位于reduce上
- 从reduce中删除SpatialIndex.Generate,然后看看为什么不按您应该的方式计算纬度和经度
public class Things_ByLocation : AbstractMultiMapIndexCreationTask<Things_ByLocation.ThingsByLocationResult>
{
public class ThingsByLocationResult
{
public string Id { get; set; }
public string UserId { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public string SKU { get; set; }
public string Name { get; set; }
}
public Things_ByLocation()
{
AddMap<Thing>(things => from t in things
select new
{
Id = t.Id,
UserId = t.UserId,
Latitude = 0,
Longitude = 0,
Name = t.Name,
SKU = t.SKU,
_ = (object)null,
});
AddMap<User>(users => from u in users
select new
{
Id = (string)null,
UserId = u.Id,
Latitude = u.Latitude,
Longitude = u.Longitude,
Name = (string)null,
SKU = (string)null,
_ = (object)null,
});
Reduce = results => from result in results
group result by result.Id into g
let lat = g.Select(x => x.Latitude).Where(x => x != 0).FirstOrDefault()
let lng = g.Select(x => x.Longitude).Where(x => x != 0).FirstOrDefault()
let userId = g.Select(x => x.UserId).Where(x => x != null).FirstOrDefault()
let name = g.Select(x => x.Name).Where(x => x != null).FirstOrDefault()
let sku = g.Select(x => x.SKU).Where(x => x != null).FirstOrDefault()
select new
{
Id = g.Key,
UserId = userId,
Latitude = lat,
Longitude = lng,
Name = name,
SKU = sku,
_ = SpatialIndex.Generate(lat, lng)
};
Store(x => x.Id, FieldStorage.Yes);
Store(x => x.UserId, FieldStorage.Yes);
TransformResults = (database, results) => from result in results
let user = database.Load<User>(result.UserId)
select new
{
Id = result.Id,
UserId = result.UserId,
Latitude = user.Latitude,
Longitude = user.Longitude,
Name = result.Name,
SKU = result.SKU,
};
}
}
public class Things\u ByLocation:AbstractMultiMapIndexCreationTask
{
公共类ThingsByLocationResult
{
公共字符串Id{get;set;}
公共字符串用户标识{get;set;}
公共双纬度{get;set;}
公共双经度{get;set;}
公共字符串SKU{get;set;}
公共字符串名称{get;set;}
}
公共事务
{
AddMap(things=>来自things中的t
选择新的
{
Id=t.Id,
UserId=t.UserId,
纬度=0,
经度=0,
Name=t.Name,
SKU=t.SKU,
_=(对象)空,
});
AddMap(用户=>来自用户中的u
选择新的
{
Id=(字符串)null,
UserId=u.Id,
纬度=美国纬度,
经度=美国经度,
Name=(字符串)null,
SKU=(字符串)null,
_=(对象)空,
});
Reduce=results=>from result in results
按result.Id将结果分组到g中
让lat=g.Select(x=>x.Latitude)。其中(x=>x!=0)。FirstOrDefault()
让lng=g.Select(x=>x.Longitude)。其中(x=>x!=0)。FirstOrDefault()
让userId=g.Select(x=>x.userId)。其中(x=>x!=null)。FirstOrDefault()
让name=g.Select(x=>x.name)。其中(x=>x!=null)。FirstOrDefault()
让sku=g.Select(x=>x.sku)。其中(x=>x!=null)。FirstOrDefault()
选择新的
{
Id=g.键,
UserId=UserId,
纬度=纬度,
经度=液化天然气,
Name=Name,
SKU=SKU,
_=空间索引生成(纬度,液化天然气)
};
存储(x=>x.Id,FieldStorage.Yes);
存储(x=>x.UserId,FieldStorage.Yes);
TransformResults=(数据库,结果)=>来自结果中的结果
让user=database.Load(result.UserId)
选择新的
{
Id=result.Id,
UserId=result.UserId,
纬度=用户。纬度,
经度=用户。经度,
Name=result.Name,
SKU=result.SKU,
};
}
}
我已经试过了,并且更新了我原来的问题。还是一个类似的问题。有什么建议吗?
public class Things_ByLocation : AbstractMultiMapIndexCreationTask<Things_ByLocation.ThingsByLocationResult>
{
public class ThingsByLocationResult
{
public string Id { get; set; }
public string UserId { get; set; }
public double Latitude { get; set; }
public double Longitude { get; set; }
public string SKU { get; set; }
public string Name { get; set; }
}
public Things_ByLocation()
{
AddMap<Thing>(things => from t in things
select new
{
Id = t.Id,
UserId = t.UserId,
Latitude = 0,
Longitude = 0,
Name = t.Name,
SKU = t.SKU,
_ = (object)null,
});
AddMap<User>(users => from u in users
select new
{
Id = (string)null,
UserId = u.Id,
Latitude = u.Latitude,
Longitude = u.Longitude,
Name = (string)null,
SKU = (string)null,
_ = (object)null,
});
Reduce = results => from result in results
group result by result.Id into g
let lat = g.Select(x => x.Latitude).Where(x => x != 0).FirstOrDefault()
let lng = g.Select(x => x.Longitude).Where(x => x != 0).FirstOrDefault()
let userId = g.Select(x => x.UserId).Where(x => x != null).FirstOrDefault()
let name = g.Select(x => x.Name).Where(x => x != null).FirstOrDefault()
let sku = g.Select(x => x.SKU).Where(x => x != null).FirstOrDefault()
select new
{
Id = g.Key,
UserId = userId,
Latitude = lat,
Longitude = lng,
Name = name,
SKU = sku,
_ = SpatialIndex.Generate(lat, lng)
};
Store(x => x.Id, FieldStorage.Yes);
Store(x => x.UserId, FieldStorage.Yes);
TransformResults = (database, results) => from result in results
let user = database.Load<User>(result.UserId)
select new
{
Id = result.Id,
UserId = result.UserId,
Latitude = user.Latitude,
Longitude = user.Longitude,
Name = result.Name,
SKU = result.SKU,
};
}
}