[英]Conditional filter retrieve partial object
如何檢索部分對象?
{
Id:123,
Name:"david",
Languages:[{b:"en"},{b:"ru"}]
}
public async Task<myObj> Get(long id, string lang=null)
{
FilterDefinition<myObj> filter = Builders<myObj>.Filter.Eq(s => s.Id, id)
& Builders<myObj>.Filter.ElemMatch(l => l.Languages, s => s.b== lang);
ProjectionDefinition<myObj> projection = Builders<Symptom>.Projection
.Include(d => d.Id)
.Include(d => d.Name)
.Include(d => d.Languages[-1]);
FindOptions<myObj> options = new FindOptions<myObj> { Projection = projection };
using (IAsyncCursor<myObj> cursor = await db.Collection.FindAsync(filter, options))
{
return cursor.SingleOrDefault();
}
}
如果我調用函數 get(123,"cn") 我希望得到:
{
Id:123,
Name:"david",
Languages:null
}
而不是空。
如何修復查詢以滿足我的需求?
我認為這將完成工作:
public async Task<myObj> Get(long id, string lang = null)
{
var res = await db.Collection.AsQueryable()
.Where(m =>
m.Id == id &&
m.Languages.Any(l => l.b == lang))
.SingleOrDefaultAsync();
return res ?? new myObj { _Id = id, Languages = null };
}
如果您只想在匹配時顯示語言(如果沒有匹配則為 null),請嘗試以下操作
public async Task<myObj> Get(long id, string lang = null)
{
FilterDefinition<myObj> filter = Builders<myObj>.Filter.Eq(s => s.Id, id)
var result = await collection.Find(filter).SingleOrDefaultAsync();
if (result != null)
result.Languages = result.Languages?.Where(lng => lng.b.Equals(lang)).ToList();
return result;
}
您將根據 ID 獲得您想要的對象。然后它將僅返回與您傳遞的語言(空或其他)匹配的那些語言。
它正在工作。 我不知道你所說的“而不是空”是什么意思。
一個次要的事情,你想不包括Languges
,而不是你投影Languages
對數組范圍與[-1]
所以它只是返回數組的最后一個元素。 最后的代碼是:
> db.ItemWithLanguages.find()
{ "_id" : ObjectId("5dfb57c9692d22eefa6e0cfe"), "Id" : 123, "Name": "david", "Languages" : [ { "B" : "en" }, { "B" : "cn" } ] }
internal class MyObj
{
public long Id { get; set; }
[BsonId]
[BsonElement("_id")]
public ObjectId MyId { get; set; }
public string Name { get; set; }
public List<Language> Languages { get; set; }
}
internal class Language
{
public string B { get; set; }
}
public static async Task<MyObj> Get(IMongoCollection<MyObj> collection, long id, string lang = null)
{
FilterDefinition<MyObj> filter = Builders<MyObj>.Filter.Eq(s => s.Id, id)
& Builders<MyObj>.Filter.ElemMatch(l => l.Languages, s => s.B == lang);
// excluding d.Languages by not including it.
// it makes Languages = null.
ProjectionDefinition<MyObj> projection = Builders<MyObj>.Projection
.Include(d => d.Id)
.Include(d => d.Name);
FindOptions<MyObj> options = new FindOptions<MyObj> { Projection = projection };
using (IAsyncCursor<MyObj> cursor = await collection.FindAsync(filter, options))
{
return cursor.SingleOrDefault();
}
}
...
string connectionString = "mongodb://localhost:27017";
var client = new MongoClient(connectionString);
var db = client.GetDatabase("test");
var myObjs = db.GetCollection<MyObj>("ItemWithLanguages");
MyObj ret;
Task.Run(async () => { ret = await Get(myObjs, 123, "cn"); }).ConfigureAwait(false).GetAwaiter()
.GetResult();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.