我正在尝试对MongoDB和C#中的文档进行 CRUD 操作。我希望在 C# 中使用具有长有意义的属性名称的固定结构化域实体,但由于每个属性的名称将保存在每个文档的 MongoDB 中,所以这不是一个好主意。这是因为属性名称将被冗余地保存在数据库中并影响总存储和性能。
我能想到的解决这个问题的解决方案是在 C# 中使用与 MongoDB 中不同的属性名称,这意味着它们之间需要映射。一种优雅的方法是合并 C# 的属性,如下所示:
class Book
{
[BsonProperty("n")]
public string Name { get; set; }
[BsonProperty("a")]
public string Author { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,文档将保存在数据库中,如下所示:
{ n: "...", a: "..." }
Run Code Online (Sandbox Code Playgroud)
我不确定 MongoDB 的 C# 驱动程序是否支持!?我自己找不到它,但我希望我找错地方了!
我的查询设置如下以允许分页。虽然这有效,但我基本上必须运行相同的查询两次才能获得查询的总匹配结果并允许分页。有什么方法可以将其合并到一个查询中吗?
public SearchResult GetResults()
{
//query is built elsewhere
var totalResults = (from i in Collection.Find(query)
select i).Count();
var results = (from i in Collection.Find(query)
select i)
.Skip(recordsToSkip)
.Take(recordsToTake)
.ToList();
//SearchResult is defined elsewhere
return new SearchResult
{
Results = results,
TotalResults = totalResults
};
}
Run Code Online (Sandbox Code Playgroud) 我的 Json 字符串为
string myjson = "[
{
"col1": "1",
"col2": "2",
"col3": "3"
},
{
"col1": "4",
"col2": "5",
"col3": "6"
},
{
"col1": "7",
"col2": "8",
"col3": "9"
}]";
Run Code Online (Sandbox Code Playgroud)
问题是:当我创建 bson 文档时,它显示
无法将 BsonArray 转换为 BsonDocument
这就是我创建 BsonDocument 的方式:
BsonDocument doc = BsonSerializer.Deserialize<BsonDocument>(myjson);
Run Code Online (Sandbox Code Playgroud)
我应该怎么办?
我尝试使用 MongoDB C# 驱动程序 (2.4.4) 表达以下查询:
db.media.aggregate({ $sample: { size: 1 }})
Run Code Online (Sandbox Code Playgroud)
这是我到目前为止所拥有的:
BsonDocument sample = new BsonDocument
{
{ "$sample", new BsonDocument { { "size", 1 } } }
};
MongoBlob mongoBlob = await _collection
.Aggregate()
.Group<MongoBlob>(sample)
.FirstOrDefaultAsync();
Run Code Online (Sandbox Code Playgroud)
我不能把sampleto放进.Aggregate(AggregateOptions options = null)去,把它放进去.Group(...)显然是错误的。也没有类似的.Sample()方法。
请帮忙。先感谢您。
我有以下表示项目的 JSON 结构
{
Id: "a",
Array1: [{
Id: "b",
Array2: [{
Id: "c",
Array3: [
{...}
]
}]
}]
}
Run Code Online (Sandbox Code Playgroud)
我需要能够Array2用新项目替换数组元素或仅用Array3新数组替换。
这是我替换数组项的代码Array2:
await Collection.UpdateOneAsync(
item => item.Id.Equals("a") &&
item.Array1.Any(a => a.Id.Equals("b")) &&
item.Array1[-1].Array2.Any(b => b.Id.Equals("c")),
Builders<Item>.Update.Set(s => s.Array1[-1].Array2[-1], newArray2Item)
);
Run Code Online (Sandbox Code Playgroud)
执行此代码时,我收到此错误:
"A write operation resulted in an error.
Too many positional (i.e. '$') elements found in path 'Array1.$.Array2.$'"
Run Code Online (Sandbox Code Playgroud)
这里是我的代码来替换Array3内Array2:
await Collection.UpdateOneAsync(
item => item.Id.Equals("a") &&
item.Array1.Any(a => a.Id.Equals("b")) && …Run Code Online (Sandbox Code Playgroud) 我想为类的所有属性设置 SetIgnoreIfDefault(true)。(这可以在存储中保存 TONS 的默认数据)
我可以为每个属性显式调用 SetIgnoreIfDefault:
BsonClassMap.RegisterClassMap<MyClass>(cm =>
{
cm.AutoMap();
cm.MapProperty(x => x.A).SetIgnoreIfDefault(true);
cm.MapProperty(x => x.B).SetIgnoreIfDefault(true);
cm.MapProperty(x => x.C).SetIgnoreIfDefault(true);
cm.MapProperty(x => x.D).SetIgnoreIfDefault(true);
cm.MapProperty(x => x.E).SetIgnoreIfDefault(true);
...
cm.SetIgnoreExtraElements(true);
});
Run Code Online (Sandbox Code Playgroud)
但是我有很多类和很多属性,如果我修改了类,我需要记住更改注册。
有没有办法在一次调用中为类的所有属性设置它?
有没有办法在全局范围内为所有属性设置它?
谢谢
使用 .NET 驱动程序在 mongodb 中创建集合时,有什么方法可以指定要验证的 json 模式吗?
我找到了有关如何使用代码设置验证器的文档,但没有找到如何使用 json 模式进行验证的文档。
我在使用 .NET 驱动程序时寻找架构验证的原因是使用代码指定验证有点冗长:
db.CreateCollectionAsync(
"Foos",
new CreateCollectionOptions<Foo>
{
Validator = FilterDefinitionBuilder<MongoCustomization>()
.And(
new FilterDefinitionBuilder<MongoCustomization>().Exists(c => c.Revision),
new FilterDefinitionBuilder<MongoCustomization>().Type(c => c.Revision, BsonType.Int32),
new FilterDefinitionBuilder<MongoCustomization>().Exists(c => c.CreatedBy)),
ValidationAction = DocumentValidationAction.Error,
ValidationLevel = DocumentValidationLevel.Strict
});
Run Code Online (Sandbox Code Playgroud) 如何在不检索整个文档的情况下在 Mongo(C# 驱动程序)中修改嵌套属性(数组)中的单个元素?
public class Element
{
public int Value {get; set;}
public string Name {get; set;}
}
public class Document
{
public Element [] Elements {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
在示例中,我想在单个查询中找到名称为“Car”的元素并将其值设置为 4。
我有一个结构看起来像这样的文档,带有嵌套的子文档
{
"_id":ObjectId("50419077c2e6a1e18a489a0f"),
"user":"Jone Doe",
"fooArray":[
{
"plot":"circle",
"color":"yellow",
},
{
"plot":"circle",
"color":"red",
},
{
"plot":"square",
"color":"green",
}
]
}
Run Code Online (Sandbox Code Playgroud)
我想在这个具有圆形图的文档中检索 fooArray 中的所有匹配元素。
这是我试过的
var filter = FilterBuilder.filter.Eq(doc => doc.User, User);
var projection = ProjectionBuilder
.Exclude(doc => doc.Id)
.Exclude(doc => doc.User)
.Include(doc => doc.FooArray)
.ElemMatch(x => x.FooArray, y => y.Plot == "circle");
var definition = new OperationDefinitions<ShapeDocument> { Filter = filter };
return await Performer.Perform(definition, async (def, collection) =>
{
var findResult = collection.Find(def.Filter).Project(projection);
var result = await findResult.SingleOrDefaultAsync();
}); …Run Code Online (Sandbox Code Playgroud) 我使用的是 MongoDB C# 驱动程序版本 2.11.0。我知道过去每个驱动程序如何不同地处理 GUID,现在有一个通用标准。出于向后兼容性的原因,默认情况下在 C# 驱动程序中不使用它。当前的建议似乎是在序列化程序上设置 GuidRepresentation。全局或单独为每个映射的 Guid 属性。
没关系,我面临的问题是对集合的查询不遵守序列化设置,只有在使用已弃用的 MongoDefaults 设置时才能正常工作。使用正确的 GuidRepresentation 正确存储文档,但查询似乎尝试匹配 CSUUID 而不是 UUID,因此它永远不会与数据库中的文档匹配。
这是一个基本的类映射:
public static void RegisterClassMaps()
{
BsonClassMap.RegisterClassMap<Widget>(cm =>
{
cm.MapIdProperty(w => w.Id)
.SetSerializer(new GuidSerializer(GuidRepresentation.Standard));
cm.MapProperty(w => w.ParentId)
.SetSerializer(new GuidSerializer(GuidRepresentation.Standard));
cm.MapProperty(w => w.Name);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个匹配 Guid 和字符串的简单查询。以下方法将始终返回 null,因为它使用 CSUUID 而不是 UUID 构建查询。
private readonly IMongoCollection<Widget> _collection;
public async Task<Widget> FindByNameAsync(Guid parentId, string name)
{
var query = _collection.Find(w =>
w.ParentId == parentId &&
w.Name = name);
return await query.SingleOrDefaultAsync();
}
Run Code Online (Sandbox Code Playgroud)
使用 …