如何将此Mongo Shell脚本转换为MongoDB C#驱动程序?
var myItems = []
var myCursor = db.Tickets.aggregate(
[
{ $match : { TicketProjectID : 49 } },
{ $project: { TicketProjectID:1, TicketID:1, concatValue: { $concat: [ "$Status", " - ", "$Name" ] } } }
// I will have a list of fields that I need to concatenate at run time. So C# query should support concatenation for "N" number of fields at run-time.
//{ $group: { _id: null, count: { $sum: 1 } } }
],
{ allowDiskUse: true }
)
//This seems like a ugly performance approach when we are working against 100k results with above match
while (myCursor.hasNext()) {
var item = myCursor.next();
if(item.concatValue.search(/mysearchkey/i) > -1)
{
myItems.push(item.TicketID)
}
}
myItems
或者是否有更好的方法在连续投影中进行字符串搜索而不是游标中的foreach,因为有些quires可能会获得50k记录。
这是我到目前为止所尝试的,(不使用聚合)
注意:修改此代码以适应公共Q& A网站。所以请将此视为伪代码
var tickets = ticketsCollection.FindSync(filter).ToList();
string concatinatedValue = string.Empty;
foreach (var ticket in tickets)
{
foreach (var field in customFieldsForThisProject)
concatinatedValue += ticket[field.Replace(" ", "_")];
if(concatinatedValue.StripHtml().contains("MysearchWord"))
{
TikectIdList.Add(ticket["TicketID"])
}
}
答案 0 :(得分:3)
感谢@ Nikola.Lukovic,他的伪代码,我提出了这个有效的解决方案。
接近一个:完全使用C#驱动程序
var ticketsCollection = _mongoConnect.Database.GetCollection<BsonDocument>("Tickets");
var dbResult = from ticket in ticketsCollection.AsQueryable()
select new
{
TicketProjectID = ticket["TicketProjectID"],
TicketID = ticket["TicketID"],
ConcatValue = ticket["Status"] + (string) ticket["Name"]
};
var matches = from dbr in dbResult
where dbr.ConcatValue.Contains(searchKey)
where dbr.ConcatValue.StartsWith(searchKey)
select dbr;
这对我的方案不适用于我想要的字段 concatenate是if type string,但是
$add
只能使用numeric
和date
类型。
方法二:使用RunCommand
并传递直接Shell命令。 这适用于所有数据类型。并且也适合我的需要。
var projectCommand =
BsonDocument.Parse(
"{ $project: { _id: -1, TicketProjectID:1, TicketID:1, concatValue: { $concat: [ \"$Status\", \" - \", \"$Name\" ] } } }");
var matchCommand =
BsonDocument.Parse("{ $match: {concatValue: { $regex: '" + searchKey + "', $options: 'i'} } }");
var pipeline = new[] {projectCommand, matchCommand};
var result = ticketsCollection.Aggregate<BsonDocument>(pipeline).ToList();
if (result.Count > 0)
return result.Select(x => (int)x["TicketID"]).ToList();
return null;
答案 1 :(得分:2)
根据给定的评论
进行编辑如果您可以使用AsQueryable(),您可以获得如下值:
var dbResult = from ticket in ticketsCollection.AsQueryable()
where ticket.TicketProjectID == 49
select new
{
TicketProjectID = ticket.TicketProjectID,
TicketID = ticket.TicketID,
ConcatValue = ticket.Status + " - " + ticket.Name
};
以后你可以这样做:
var result = from dbr in dbResult
where dbr.ConcatValue.Contains("something") //or
where dbr.ConcatValue.StartsWith("something")//or you can use regex
select dbr;
注意:由于某种原因,类型
Status
的{{1}}和Name
属性需要属于Ticket
类型才能连接,因为mongo驱动程序赢了&#39; t识别来自其他类型的String
的呼叫。
如果要连接其他类型的属性,可以将它们与数据库分开,而不是在本地连接它们。
ToString()
或者你可以像这样编写shell命令并将其放在一个字符串中:
note, i'm not that good with mongo shell i could mess something up but you can see in which way you could go
然后使用var command = @"db.Tickets.aggregate(
[
{ $project: { TicketProjectID:1, TicketID:1, concatValue: { $concat: [ "$Status", " - ", "$Name" ] } } },
{ $match : { TicketProjectId : 49, concatValue : { $regex : /mysearchkey/i } } }
],
{ allowDiskUse : true }
);";
中的RunCommandAsync
方法在c#中执行它。
MongoDatabase