. net使用MongoDB根据子文档列表进行选择
本文关键字:列表 行选 选择 文档 使用 MongoDB net | 更新日期: 2023-09-27 18:13:00
我有一个客户数据库,其中包含客户ip地址范围的列表,以便他们访问系统。
public class Customer
{
[BsonId]
public ObjectId Id { get; set; }
public string Name { get; set; }
public List<IPRange> IPRanges { get; set; }
}
public class IPRange
{
public int Lower { get; set; }
public int Upper { get; set; }
}
ip被转换为整数,因此更容易(或至少我认为是)将它们与传入ip地址进行比较。
MongoDB中的文档是这样的
{
"_id": ObjectID("55f9ab5ac95fb323d8b724a8"),
"Name": "Customername",
"IPRanges": [
{
"Lower": 134743044,
"Upper": 134744072
},
{
"Lower": 3494108380,
"Upper": 3494108894
}
],
}
那么问题是,如何根据IP数组比较传入IP和客户IP ?如果不可能,如何以更好的方式做到这一点?
我已经尝试了很多组合,没有一个是有效的。我已经设法得到它的工作,如果上和下的ip是相同的。
这是我得到的最接近的解
private async static Task<bool> check(string ip = "")
{
db = Connect();
var intIp = IPCalculator.IPToInt(ip); //converts the ip from string form e.g. "8.8.8.8" to integer
var lowerFilter = Builders<IPRange>.Filter.Gte("Lower", intIp);
var upperFilter = Builders<IPRange>.Filter.Lte("Upper", intIp);
List<FilterDefinition<IPRange>> filters = new List<FilterDefinition<IPRange>>();
filters.Add(lowerFilter);
filters.Add(upperFilter);
var customerFilter = Builders<Customer>.Filter.ElemMatch<IPRange>(ca => ca.IPRanges, Builders<IPRange>.Filter.And(filters));
var customerCollection = db.GetCollection<Customer>("Customer").Find(customerFilter);
var customerList = await customerCollection.ToListAsync();
if (customerList.Count > 0)
{
return true;
}
return false;
}
看来你搞砸了一点:
var lowerFilter = Builders<IPRange>.Filter.Gte("Lower", intIp);
var upperFilter = Builders<IPRange>.Filter.Lte("Upper", intIp);
因为这意味着Lower>= ip和Upper <= ip。你需要:
var lowerFilter = Builders<IPRange>.Filter.Lte("Lower", intIp);
var upperFilter = Builders<IPRange>.Filter.Gte("Upper", intIp);