使用Mongodb-CSharp Driver调用函数

本文关键字:函数 调用 Driver Mongodb-CSharp 使用 | 更新日期: 2023-09-27 18:05:03

目前,我在MongoDb的Csharp驱动程序LinQ上工作,我有问题实现一种方法,如在MongoDb上调用存储函数。实际上,我知道MongoDB没有存储过程机制。我需要有人给出建议或解决方案来解决这个问题。重要的是,数据将以某种方式在mongodb中完成,而无需在内存中完成。例如,我想返回一个列表与过滤器条件,由自定义方法实现。此方法根据字段依赖项进行计算。

一个例子在内存中完成。

var list = collection.AsQueryable<Rule>().ToList();    
var result = list.Where(x => x.Active && CalcMethod(x.Rule)> 5);

和自定义方法。

public static int CalcMethod(Rule rule)
{           
    if(rule.Active)   
        // bypass check null 
        return rule.Weight.Unit * rule.Weight.Value;
    else
       // return something here
}

CalcMethod方法就像SQL Server中的一个函数。无论我们是否可以用MongoDb或其他方式做到这一点,期望我们可以注入一个方法来计算数据和过滤,而无需在内存中完成。

使用Mongodb-CSharp Driver调用函数

我认为你可以使用聚合(或者使用MapReduce处理复杂的事情)。即:

async void Main()
{
  var client = new MongoClient("mongodb://localhost");
  var db = client.GetDatabase("TestSPLike");
  var col = db.GetCollection<Rule>("rules"); 
  await client.DropDatabaseAsync("TestSPLike"); // recreate if exists
  await InsertSampleData(col); // save some sample data
  var data = await col.Find( new BsonDocument() ).ToListAsync();
  //data.Dump("All - initial");
/*  
  db.rules.aggregate(
   [
     { $match: 
        {
         "Active":true
        }
     }, 
     { $project: 
        { 
         Name: 1, 
         Active: 1, 
         Weight:1, 
         Produce: { $multiply: [ "$Weight.Unit", "$Weight.Value" ] }
        } 
     },
     { $match: 
        {
          Produce: {"$gt":5}
        }
     }
   ]
)
*/ 
var aggregate = col.Aggregate()
  .Match(new BsonDocument{ {"Active", true} })
  .Project( new BsonDocument {
      {"Name", 1}, 
      {"Active", 1}, 
      {"Weight",1}, 
      {"Produce", 
         new BsonDocument{
           { "$multiply", new BsonArray{"$Weight.Unit", "$Weight.Value"} }
        }} 
  } )
  .Match( new BsonDocument { 
       { "Produce", 
          new BsonDocument{ {"$gt",5} } 
          }
          })
  .Project( new BsonDocument {
      {"Name", 1}, 
      {"Active", 1}, 
      {"Weight",1} 
      } );
  var result = await aggregate.ToListAsync();
  //result.Dump();
}
private async Task InsertSampleData(IMongoCollection<Rule> col)
{
 var data = new List<Rule>() {
   new Rule { Name="Rule1", Active = true, Weight = new Weight { Unit=1, Value=10} },
   new Rule { Name="Rule2", Active = false, Weight = new Weight { Unit=2, Value=3} },
   new Rule { Name="Rule3", Active = true, Weight = new Weight { Unit=1, Value=4} },
   new Rule { Name="Rule4", Active = true, Weight = new Weight { Unit=2, Value=2} },
   new Rule { Name="Rule5", Active = false, Weight = new Weight { Unit=1, Value=5} },
   new Rule { Name="Rule6", Active = true, Weight = new Weight { Unit=2, Value=4} },
 };
 await col.InsertManyAsync( data,new InsertManyOptions{ IsOrdered=true});
}
public class Weight
{
  public int Unit { get; set; }
  public int Value { get; set; }
}
public class Rule
{
  public ObjectId _id { get; set; }
  public string Name { get; set; }
  public bool Active { get; set; }
  public Weight Weight { get; set; }
}