Mongodb C# драйвер Строка выполнения содержит запрос к свойству во встроенном документе - PullRequest
1 голос
/ 20 февраля 2020

У меня есть упрощенная модель, приведенная ниже:

public class Entity
{
    public Guid Id { get; set; }

    public IList<ComponentProperty> Components { get; private set; }

}

public class ComponentProperty
{
    public string PropertyName { get; set; }

    public string Value { get; set; }

}

Я хочу иметь возможность найти любую сущность, строка значения свойства которой содержит строку поиска, и с этой целью я написал следующий запрос, основываясь на рекомендации здесь , который неявно использует Regex:

var query = _context.GetCollection<Entity>()
                        .AsQueryable()
                        .Where(t => t.Components.Any(c => c.Value.ToLower() == queryOptions.Filter));

Этот запрос создает следующий json и (неправильно) возвращает 0 строк:

aggregate([{ "$match" : { "Components" : { "$elemMatch" : { "Value" : /^'green'$/i} } } }])

Однако, Ручной запрос, который дает правильные результаты, приведен ниже:

aggregate([{ "$match" : { "Components" : { "$elemMatch" : { "Value" :  {$regex: '.*green.*' } } } } }])

Возможно, что-то, что я упустил в своем подходе с использованием драйвера c#, и любые указатели будут высоко оценены.

1 Ответ

1 голос
/ 20 февраля 2020

измените ваше предложение where на следующее:

.Where(e => e.Components.Any(c => c.Value.ToLower().Contains(queryOptions.Filter)))

, которое производит это агрегирование:

db.Entity.aggregate([
    {
        "$match": {
            "Components.Value": /green/is
        }
    }
])

вот тестовая программа:

using MongoDB.Entities;
using MongoDB.Entities.Core;
using System.Collections.Generic;
using System.Linq;

namespace StackOverFlow
{
    public class Ntity : Entity
    {
        public IList<ComponentProperty> Components { get; set; }
    }

    public class ComponentProperty
    {
        public string PropertyName { get; set; }

        public string Value { get; set; }

    }

    public static class Program
    {
        private static void Main()
        {
            new DB("test");

            new Ntity
            {
                Components = new List<ComponentProperty> {
                    new ComponentProperty {
                        PropertyName = "test",
                        Value = "the RED color" }
                }
            }.Save();

            new Ntity
            {
                Components = new List<ComponentProperty> {
                    new ComponentProperty {
                        PropertyName = "test",
                        Value = "the Green color" }
                }
            }.Save();

            var result = DB.Queryable<Ntity>()
                           .Where(e => e.Components.Any(c => c.Value.ToLower().Contains("green")))
                           .ToList();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...