使用“ObjectId”查询 MongoDB

问题描述 投票:0回答:6

我已将

document
插入到 MongoDB 中,但没有
id
。我想通过搜索它们的 MongoDB
ObjectId
来检索它们,它已被分配给 默认

这是我的尝试-

var query_id = Query.EQ("_id", "50ed4e7d5baffd13a44d0153");
var entity = dbCollection.FindOne(query_id);
return entity.ToString();

我收到以下错误-

发生了“System.NullReferenceException”类型的第一次机会异常

有什么问题吗?

c# .net mongodb mongodb-.net-driver
6个回答
68
投票

您需要创建

ObjectId
的实例,然后使用该实例进行查询,否则您的查询会将
ObjectId
与字符串进行比较,而无法找到匹配的文档。

这应该有效:

var query_id = Query.EQ("_id", ObjectId.Parse("50ed4e7d5baffd13a44d0153"));
var entity = dbCollection.FindOne(query_id);
return entity.ToString();

37
投票

C#最新的官方MongoDB.Driver中写下这个-

var filter_id = Builders<MODEL_NAME>.Filter.Eq("id", ObjectId.Parse("50ed4e7d5baffd13a44d0153"));
var entity = dbCollection.Find(filter).FirstOrDefault();
return entity.ToString();

我们可以实现相同的结果,而无需将

id
从字符串转换为
ObjectId
。但是,我们必须在模型类中的
[BsonRepresentation(BsonType.ObjectId)]
属性之前添加
id

甚至可以使用 lambda 表达式-

进一步简化代码
var entity = dbCollection.Find(document => document.id == "50ed4e7d5baffd13a44d0153").FirstOrDefault();
return entity.ToString();

4
投票

如果您在 2018 年,想要复制/粘贴仍然有效的代码或纯字符串语法;

    [Fact]
    public async Task QueryUsingObjectId()
    {
        var filter = Builders<CosmosParkingFactory>.Filter.Eq("_id", new ObjectId("5b57516fd16cb04bfc35fcc6"));
        var entity = stocksCollection.Find(filter);
        var stock = await entity.SingleOrDefaultAsync();
        Assert.NotNull(stock);

        var idString = "5b57516fd16cb04bfc35fcc6";
        var stringFilter = "{ _id: ObjectId('" + idString + "') }";
        var entityStringFiltered = stocksCollection.Find(stringFilter);
        var stockStringFiltered = await entityStringFiltered.SingleOrDefaultAsync();
        Assert.NotNull(stockStringFiltered);
    }

3
投票

所选答案是正确的。对于任何对 Query.EQ 感到困惑的人,这里是另一种编写基本更新的方法(更新整个 mongodb 文档):

string mongoDocumentID = "123455666767778";
var query = new QueryDocument("_id", ObjectId.Parse(mongoDocumentID)); 
var update = new UpdateDocument { { "$set", documentToSave } };
mongoCollection.Update(query, update, UpdateFlags.Multi);

当你想真正通过对象ID搜索时,需要ObjectId对象,否则它是在比较字符串和objectid类型,并且不会匹配。 Mongo 在这种方式上对类型非常严格,无论字段名称是否正确。


0
投票

你也可以这样做,它

public static ObjectId GetInternalId(string id)
    {
        if (!ObjectId.TryParse(id, out ObjectId internalId))
            internalId = ObjectId.Empty;

        return internalId;
    }

然后在你的方法中你可以做这样的事情

ObjectId internalId = GetMongoId.GetInternalId(id);
        return await YourContext.YourTable.Find(c => c.InternalId == internalId).FirstOrDefaultAsync();

注意:GetInternalId 中的 id 参数是该方法的参数。如果您需要这样:

public async Task<YourTable> Find(string id)
    {
        ObjectId internalId = GetMongoId.GetInternalId(id);
        return await YourContext.YourTable.Find(c => c.InternalId == internalId).FirstOrDefaultAsync();
    }

希望它也有帮助。


0
投票

使用 MongoDB.Driver 2.23.1 和 dotnet 6.0

// Example schema
public class NoteTags
{
    [GraphQLIgnore]
    [BsonId]
    public ObjectId Id { get; set; }

    [BsonElement("name")]
    public string Name { get; set; }
}

Mongo 数据库查询

_id

using MongoDB.Bson;
using MongoDB.Driver;

class SampleQueryByID {
  public GetTags() {
    var client = new MongoClient( /** Mongo Settings */ );
    var db = client.GetDatabase("db");
    var tagsCollection = db.GetCollection < NoteTags > ("tags");

    var findOptions = new FindOptions {
      BatchSize = 10
    };
    FilterDefinition < NoteTags > filter; = Builders < NoteTags > .Filter.In(
      "_id",
      TagsIds.Select(tag => ObjectId.Parse(tag)) // Very important to parse
    );

    // res variable to hold the mongo db query result
    var res = new List < NoteTags > ();

    // use the above filter and filter option
    using(var cursor = tagsCollection.Find(filter, findOptions).ToCursor()) {
      if (cursor.MoveNext()) {
        var d = cursor.Current.ToList();

        for (int i = 0; i < d.Count; i++) {
          res.Add(d[i]);
        }
      }
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.