В моей базе данных mongodb есть массив объектов, который выглядит примерно так.
[
{
_id: 123,
info: [
{
name: John,
random: ['31', 'food', 'sleep']
}
]
},
{
_id: 234,
info: [
{
name: Amy,
random: ['tv', 'food', 'sleep']
}
]
},
{
_id: 345,
info: [
{
name: John,
random: ['cars', 'tv31', 'sleep']
}
]
},
]
В С#, как мне фильтровать информацию, где имя Джон, а случайное число содержит 31? Я также не знаю, в чем разница между AnyIn и In.
🤔 А знаете ли вы, что...
C# активно развивается и обновляется, с появлением новых версий и функциональности.
в С#, как мне фильтровать информацию, где имя
"John"
и случайное значение"31"
?
У вас должна быть возможность запросить свойство info
каждого элемента данных, чтобы отфильтровать результаты, например:
var results = data.Where(item =>
item.info.Any(info =>
info.name == "John" &&
info.random.Any(random => random == "31")));
Следующий код работает.
public class Item
{
[BsonId]
[BsonRepresentation(BsonType.Int32)]
public int Id { get; set; }
public IEnumerable<Person> info { get; set; }
}
public class Person
{
public string name { get; set; }
public List<string> random { get;set; }
}
var filter = Builders<Item>.Filter.Where(item => item.info.Any(info => (info.random.Any(random => random.Contains("31"))) && (info.name == "John")));
var results = collection1.Find(filter).ToList();
var results = collection1.AsQueryable()
.Where(item => item.info.Any(info => (info.random.Any(random => random.Contains("31"))) && (info.name == "John")))
.ToList();
Запрос LINQ (который рассматривается другими ответчиками) работает и проще для тех, кто не знаком с запросом MongoDB Fluent.
Для тех, кто ищет синтаксис MongoDB Fluent:
Предположим, что ваши классы моделей такие, как показано ниже:
public class RootModel
{
[BsonId]
public int Id { get; set; }
public InfoModel[] Info { get; set; }
}
[BsonNoId]
public class InfoModel
{
public string Name { get; set; }
public string[] Random { get; set; }
}
Вам следует работать с .ElemMatch
и .AnyIn
:
var filter = Builders<RootModel>.Filter.ElemMatch(x => x.Info,
Builders<InfoModel>.Filter.Eq(y => y.Name, "John")
& Builders<InfoModel>.Filter.AnyIn(y => y.Random, new string[] { "31" }));
На вопрос владельца сообщения о различиях между .In
и .AnyIn
:
In
работает, когда ваше поле представляет собой одно значение и используется для сопоставления любого элемента из предоставленного входного массива.
AnyIn
работает, когда ваше поле представляет собой массив и используется для сопоставления любого элемента из предоставленного входного массива.
В зависимости от вашего сценария вы получите синтаксическую ошибку при использовании .In
для реализации In
, как показано ниже:
public FilterDefinition<TDocument> In<TField>(Expression<Func<TDocument, TField>> field, IEnumerable<TField> values)
{
return In(new ExpressionFieldDefinition<TDocument, TField>(field), values);
}
Если только вы не проверяете весь массив Random
, который точно соответствует массиву, например:
random: {
$in: [['31', 'food', 'sleep'], ...]
}
Итак, это работает с In
:
Builders<InfoModel>.Filter.In(y => y.Random,
new string[][] { new string[] { "31", "food", "sleep" } })
Это другая история сопоставления точного значения массива по сравнению с текущим вопросом, который требует сопоставления любого элемента массива.