5

I am trying to implement the text search functionality with the nested array documents in MongoDB using C#. And I have a MongoDB collection in the below format.

{    
   "_id" : ObjectId("56c6f03ffd07dc1de805e84f"),
   "Customers" : {
            "Contact" : [ 
                           [
                             { 
                                "FirstName" : "Swetha", 
                                "LastName" : "DevAnand"
                             }
                           ]
                        ]
                   }
}

Mongo Query:

  db.test_collection.find({"Customers.Contact":{$elemMatch:{$elemMatch:{LastName: /.*Dev.*/}}}});

As in the above MongoDB query, I wanted to do a LIKE Search with the innermost array of BSON document using C#. However, I have acheived this using nested $elemMatch in Mongo Query. But while trying to do the same in C#, it expects the fieldname for every ElemMatch Query.In the above case, the innermost array of Contact field does not have any explicit field name. So far, I have tried all the below C# code to implement the scenario, but none of them helps.

var regex = new BsonRegularExpression(searchVal,"i");

query = Query.And(Query.ElemMatch("Customers.Contact", Query.And(Query.ElemMatch("LastName", Query.Matches("LastName", regex)))));
query = Query.And(Query.Matches("Customers.Contact.$.LastName",regex));
query = Query.And(Query.ElemMatch("Customers.Contact.$", Query.EQ("LastName", regex)));                 
query = Query.And(Query.ElemMatch("Customers.Contact.$", Query.Matches("LastName", regex)));
query = Query.And(Query.ElemMatch("Customers.Contact", Query.And(Query.ElemMatch("$", Query.EQ("LastName", regex)))));

Any help is really appreciated.

3
  • SO isn't a code conversion service. Check Mongo C# driver docs and do it yourself Commented Feb 23, 2016 at 10:31
  • @Matias. Thanks for ur reply. I have gone through Mongo C# driver docs and it is of no help in this scenario, as in my MongoDB query i wanted to implement $elematch without specifying the fieldname of innermost array. And I am struggling to do the same in C#, where it expects the fieldname for every ElemMatch Query.Thus seeking for help in SO.. Commented Feb 23, 2016 at 10:50
  • I believe you should explain your issue in the question's body instead of a comment. Your current text as is is just "please translate my code to C#" :( Commented Feb 23, 2016 at 11:11

2 Answers 2

2

After a week of struggle, found a way. The best method to implement the above MongoDB Query is to deserialize it into a BsonDocument which in return will be passed to FindAsync as filter.

var bQuery = "{'Customers.Contact':{$elemMatch:{$elemMatch:{LastName: /.*Dev.*/}}}}";
var filter = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<BsonDocument>(bQuery);
var result = collection.FindSync(filter).ToList();

Thanks to Mr.Saleem. Please refer to below link for more details. How to implement MongoDB nested $elemMatch Query in C#

Sign up to request clarification or add additional context in comments.

Comments

1

I am not aware about your context - so get this as a try to help you. Be aware that contact is a list instead of array That will help you to build own filter expressions

namespace ClassLibrary1
{
    using System;
    using System.Collections.Generic;
    using System.Linq.Expressions;

    using MongoDB.Driver;

    /// <summary>
    /// The class 1.
    /// </summary>
    public class Class1
    {
        /// <summary>
        /// The get data.
        /// </summary>
        public async void GetData()
        {
            var context = new Context();
            var searchString = "1234";
            Expression<Func<SomeThing, bool>> filter = x =>
            x.Contact.Exists(s => s.FirstName == searchString
            && x.Contact.Exists(l=>l.LastName == searchString));
            var result = await context.SomeThingCollection.FindAsync(filter);
        }
    }

    /// <summary>
    /// The context.
    /// </summary>
    public class Context
    {
        public const string CONNECTION_STRING_NAME = " ";
        public const string DATABASE_NAME = " ";
        public const string COLLECTION_NAME = "name";
        private static readonly IMongoClient _client;
        private static readonly IMongoDatabase _database;
        static Context()
        {
            var connectionString = "connectionString";
            _client = new MongoClient(connectionString);
            _database = _client.GetDatabase(DATABASE_NAME);
        }
        public IMongoCollection<SomeThing> SomeThingCollection
        {
            get
            {
                return _database.GetCollection<SomeThing>(COLLECTION_NAME);
            }
        }
    }

    public class SomeThing
    {
        public List<Contact> Contact { get; set; }
    }

    public class Contact
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }
}

1 Comment

Thanks Professor. That was helpful. But in my scenario, the above code is not working due the list of arrays in json format. eg: contact : [ [ {} ],[ {} ] ]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.