简体   繁体   English

Mongo C# 驱动程序 - 长度支持?

[英]Mongo C# driver - Length support?

The docs says I can use : 文档说我可以使用:

Find(x => x.FavoriteNumbers.Length == 3);

If I write:如果我写:

await col.Find(f=>f.AuthType > 2).ToListAsync()

I do get the expected result because all AuthType are greater than 2 .我确实得到了预期的结果,因为所有AuthType都大于2

在此处输入图片说明

But now, let's say that I want to filter all records with Id.Length>2 :但是现在,假设我想用Id.Length>2过滤所有记录:

await col.Find(f=>f.Id.Length>2).ToListAsync();

This returns 0 records.这将返回 0 条记录。

Question:题:

How can I get all the records with Id's Length >2 ?如何获取 Id's Length >2 的所有记录?

I've already read this question , but with no answer and the dup is not in c#我已经阅读过这个问题,但没有答案,并且 dup 不在 c# 中

In Visual Studio you can write below line of code and try to inspect it by hovering:在 Visual Studio 中,您可以编写以下代码行并尝试通过悬停来检查它:

var query = await col.Find(f=>f.Str.Length>2)

What happens is that MongoDB will transalte it into regular expression like {find({ "Str" : /^.{3,}$/s })} and this regex gets executed on the database side.发生的情况是 MongoDB 会将其转换为正则表达式,如{find({ "Str" : /^.{3,}$/s })}并且这个正则表达式在数据库端执行。 Nothing unexpected.没有什么意外。 The problem occurs when you change Str into Id which gets translated into:当您将Str更改为Id时会出现问题,该Id被转换为:

{find({ "_id" : /^.{3,}$/s })}

and you get no result as your field's name is still Id .并且您没有得到任何结果,因为您的字段名称仍然是Id The reason why it's happening is described here .它发生的原因在此处描述。 So MongoDB driver by convention infers that field named Id should be translated into _id .因此,MongoDB 驱动程序按照惯例推断应将名为Id字段转换为_id To fix that you can explicitly specify on your data model which field should be considered as _id using BsonId attribute:要解决此问题,您可以使用BsonId属性在数据模型上明确指定应将哪个字段视为_id

public class ModelClass
{
    [BsonId]
    public ObjectId RealId { get; set; }
    public string Id { get; set; }
}

EDIT:编辑:

To apply type conversion (int -> string) you have to rely on $toString operator introduced in MongoDB.要应用类型转换(int -> string),您必须依赖 MongoDB 中引入的$toString运算符。 The idea is simple: you add new field using $addFields and then run $strLenCP on it to verify string length.想法很简单:您使用$addFields添加新字段,然后在其上运行$strLenCP以验证字符串长度。 Unfortunately there's no easy way to do it in C# using strongly typed way so you can use BsonDocument class which lets you use strings as Aggregation Pipeline definition:不幸的是,使用强类型方式在 C# 中没有简单的方法可以做到这一点,因此您可以使用BsonDocument类,该类允许您使用字符串作为聚合管道定义:

var q = Col.Aggregate()
            .AppendStage<BsonDocument>(BsonDocument.Parse("{ $addFields: { AuthTypeInt: { $toString: \"$AuthType\" } } }"))
            .Match(BsonDocument.Parse("{ $expr: { $gt: [ { \"$strLenCP\": \"$AuthTypeInt\" }, 2 ] } }"));

var data = await q.ToListAsync();

The code looks ugly but it should be a way faster than running plain JavaScript (more here )代码看起来很丑,但它应该比运行普通的 JavaScript 快得多(更多在这里

I've managed to do it in a very ugly way, involving JS:我设法以一种非常丑陋的方式做到了,涉及 JS:

var ll=new BsonDocument("$where", new BsonJavaScript("function() { return this.authType.toString().length>2; }"));

var t2 = await col.Find(ll).ToListAsync();

在此处输入图片说明

What is the C# equivalent solution?什么是 C# 等效解决方案?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM