Existem algumas maneiras de conseguir isso dependendo se seus dados não estruturados são conhecidos em tempo de compilação ou em tempo de execução.
Para o tipo de compilação, você pode modelar sua projeção dos dados e usar o construtor de projeção para especificar como sua projeção deve funcionar
var collection = database.GetCollection<Customer>("customers");
var document = new Customer(){Name = "Joe Bloggs", Age = 30, Address = "York"};
collection.InsertOne(document);
var projection = Builders<Customer>
.Projection
.Include(x => x.Id).Include(x => x.Age);
var customerProjection = await collection.Find(x => true)
.Project<CustomerProjection>(projection)
.FirstAsync();
Acima, especificamos o tipo de retorno como o argumento genérico, mas se omitirmos isso, retornaremos um
BsonDocument
que pode ser útil dependendo do seu uso var bsonDocument = await collection.Find(x => true)
.Project(projection)
.FirstAsync();
Também podemos obter o mesmo resultado usando a expressão linq:
var projection = await collection.Find(x => true)
.Project(x => new {x.Id, x.Age}).FirstAsync();
Isso resultará no retorno de um tipo anônimo com Id e Age.
No entanto, se não conhecemos os dados em tempo de compilação e estamos baseando os campos de strings mágicas em tempo de execução, você precisará passar em
BsonDocument
para o GetCollection
método:var collection = database.GetCollection<BsonDocument>("customers");
Agora você poderá fazer os dois métodos acima para projetar o documento bson, mas será por campo.
No entanto, aconselho tentar usar os construtores do Project, pois isso facilitará um pouco sua vida:
var projectionDefinition = Builders<BsonDocument>.Projection
.Include("age")
.Exclude("_id");
var projection = await collection.Find(x => true)
.Project(projectionDefinition)
.FirstAsync();