Как фильтровать массив объектов, равный имени и содержащий значение?

В моей базе данных 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.

Когда вы говорите «содержит» 31, вы имеете в виду, что строка содержит подстроку 31 или там, где она содержит именно «31»? Первый не будет эффективным запросом Mongo, если у вас нет текстового индекса на info.random (и, возможно, даже тогда — я особо не использовал текстовые индексы Mongo).

ProgrammingLlama 15.08.2024 04:21
data.Where(x => x.info.Any(y => y.name == "John" && y.random.Any(z => z == "31"))); должно помочь. Или, если вы имели в виду, что случайные строки содержат 31, то data.Where(x => x.info.Any(y => y.name == "John" && y.random.Any(z => z.Contains("31")))); должно работать.
Sani Huttunen 15.08.2024 05:14

Всегда ли поле info представляет собой массив с одним объектом, как показано (если да, то почему это массив)?

user20042973 15.08.2024 05:24

@user20042973 user20042973 эй, нет, это не всегда один объект, но я не думал, что мне нужно добавить больше объектов для этого вопроса.

tony nguyen 15.08.2024 14:50

я ищу, где имя равно Джону, а любая строка в случайном порядке содержит 31

tony nguyen 15.08.2024 14:52

спасибо @SaniHuttunen

tony nguyen 15.08.2024 17:10
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
67
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

в С#, как мне фильтровать информацию, где имя "John" и случайное значение "31"?

У вас должна быть возможность запросить свойство info каждого элемента данных, чтобы отфильтровать результаты, например:

var results = data.Where(item => 
    item.info.Any(info => 
        info.name == "John" && 
        info.random.Any(random => random == "31")));

Имейте в виду, что OP может означать случайные строки, содержащие 31. Тогда это должно включать объект с _id = 345, поскольку tv31 содержит 31. (См. мой комментарий к вопросу).

Sani Huttunen 15.08.2024 11:57

Следующий код работает.

    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" } })

Это другая история сопоставления точного значения массива по сравнению с текущим вопросом, который требует сопоставления любого элемента массива.

Другие вопросы по теме

Похожие вопросы

С# Получение номера месяца из короткого месяца
Цикл или рекурсивный метод не могут получить данные
Нужна помощь в анализе HTML-разметки с помощью CSVHelper через мой .NET API
После перезапуска игры цели не появляются
Таблица данных JQuery – сортировка столбцов не работает в
Как я могу исправить связь многие-ко-многим между двумя объектами, чтобы третья таблица автоматически заполнялась в структуре сущностей и веб-API (С#)
Как я могу зарегистрировать HTTP-ответ с помощью промежуточного программного обеспечения в функциях Azure, выполняющих изолированный процесс .NET 8?
Контекст Testcontainers .NET 8 db, похоже, не обновляется в [Факт], проблема решена, ищет объяснение
Переписать удаление служебной шины Azure
Невозможно вставить явное значение для столбца идентификаторов в таблице «Обсуждаемые продукты», если для параметра IDENTITY_INSERT установлено значение OFF