判断一组ID中哪些ID仍在数据库中的有效方法(即将输入ID与集合ID相交)MongoDb C#
我收集了大约8000万份文件。 通过API,用户可以验证数据库中是否仍存在一组ID(输入集)。 输入集可能相当大,但我会将验证分为大约10000个ID的块。 基本上,我希望得到数据库ID和输入集之间的交集 我想和Linq一起做这件事,但欢迎其他建议 下面是一些示例代码,显示了我的场景和我迄今为止所尝试的内容 第一种方法是我要做的,但它抛出了一个NotSupportedException:表达式树中不支持Intersect方法: 第二种方法有效,但在大型集合上速度非常慢 第三种方法比第二种方法快,但我必须在内存中加载8000万个ID 我们试图坚持使用C#wrapper提供的linq接口,但有时会遇到困难。任何指点都很感激。我想在$setCrossion中使用不同的构建器和管道定义是有出路的,但我无法理解关于这一点的c#文档判断一组ID中哪些ID仍在数据库中的有效方法(即将输入ID与集合ID相交)MongoDb C#,c#,mongodb,C#,Mongodb,我收集了大约8000万份文件。 通过API,用户可以验证数据库中是否仍存在一组ID(输入集)。 输入集可能相当大,但我会将验证分为大约10000个ID的块。 基本上,我希望得到数据库ID和输入集之间的交集 我想和Linq一起做这件事,但欢迎其他建议 下面是一些示例代码,显示了我的场景和我迄今为止所尝试的内容 第一种方法是我要做的,但它抛出了一个NotSupportedException:表达式树中不支持Intersect方法: 第二种方法有效,但在大型集合上速度非常慢 第三种方法比第二种方法快,
private string[] FilterOnExistInDatabase1(string[] candidates)
{
// Query<T> is just a wrapper to the collection and returns a IQueryable<T>
return mongoRepository.Query<TestModel>().Select(x => x.Id).Intersect(candidates).ToArray();
}
private string[] FilterOnExistInDatabase2(string[] candidates)
{
// Query<T> is just a wrapper to the collection and returns a IQueryable<T>
return mongoRepository.Query<TestModel>().Select(x => x.Id).Where(x => candidates.Contains(x)).ToArray();
}
private string[] FilterOnExistInDatabase3(string[] candidates)
{
// Query<T> is just a wrapper to the collection and returns a IQueryable<T>
var allExistingIds = mongoRepository.Query<TestModel>().Select(x => x.Id).ToArray();
var existingCandidates = allExistingIds.Intersect(candidates).ToArray();
return existingCandidates;
}
[Test]
public void SampleQuery()
{
var models = Enumerable.Range(0, 10).Select(x => new TestModel()).ToArray();
mongoRepository.InsertMany(models, CancellationToken.None);
var deletedId = "I no longer exist";
var candidates = models.Select(x => x.Id).Concat(new []{deletedId}).ToArray();
var existingCandidates = FilterOnExistInDatabase3(candidates);
Assert.That(existingCandidates.Length, Is.EqualTo(models.Length));
Assert.False(existingCandidates.Contains(deletedId));
Assert.That(existingCandidates.Length, Is.EqualTo(candidates.Length - 1));
}
private string[]filternexistindatabase1(string[]candidates)
{
//查询只是集合的包装,并返回IQueryable
返回mongoRepository.Query().Select(x=>x.Id).Intersect(candidates.ToArray();
}
私有字符串[]FilterNexistinDatabase2(字符串[]候选)
{
//查询只是集合的包装,并返回IQueryable
返回mongoRepository.Query().Select(x=>x.Id).Where(x=>candidates.Contains(x)).ToArray();
}
私有字符串[]FilterNexistinDatabase3(字符串[]候选)
{
//查询只是集合的包装,并返回IQueryable
var allExistingIds=mongoRepository.Query().Select(x=>x.Id.ToArray();
var existingCandidates=allExistingIds.Intersect(candidates.ToArray();
返回现有候选人;
}
[测试]
public void SampleQuery()
{
var models=Enumerable.Range(0,10)。选择(x=>newtestmodel()).ToArray();
mongoRepository.InsertMany(models,CancellationToken.None);
var deletedId=“我不再存在”;
varcandidates=models.Select(x=>x.Id).Concat(new[]{deletedId}).ToArray();
var existingCandidates=filternexistingdatabase3(候选者);
Assert.That(existingCandidates.Length,Is.EqualTo(models.Length));
Assert.False(existingCandidates.Contains(deletedId));
Assert.That(existingCandidates.Length,Is.EqualTo(candidates.Length-1));
}
以下方法如何?基本上,您可以获取数据库中存在的一个ID数组,并使用linq在客户端生成交集,以获取无效/已删除的ID
使用MongoDB.Bson;
使用MongoDB.Entities;
使用MongoDB.Entities.Core;
使用制度;
使用System.Linq;
命名空间堆栈溢出
{
公共类项:实体
{
公共字符串名称{get;set;}
}
公共课程
{
私有静态void Main(字符串[]args)
{
新数据库(“测试”、“本地主机”);
var one=新项{Name=“one”};one.Save();
var two=新项{Name=“two”};two.Save();
var thr=新项{Name=“three”};thr.Save();
var inputIDs=new[]{one.ID,two.ID,ObjectId.GenerateNewId().ToString()};
var validIDs=DB.Queryable()//供官方驱动程序使用:collection.AsQueryable()
.Where(i=>inputIDs.Contains(i.ID))
.选择(i=>i.ID)
.ToArray();
var deletedIDs=inputIDs.Except(validis.ToArray();
}
}
}
从理论上讲,这应该比上面的第二种方法快,因为它不会导致集合中每个ID的投影。如果您可以接受这种方法,我很想知道mongodb为8000万个文档完成这项任务需要多少毫秒