如何使用C#从MongoDB查询JSON数组中的特定项目[英] How to query specific item in json array return from mongodb using c#

本文是小编为大家收集整理的关于如何使用C#从MongoDB查询JSON数组中的特定项目的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我有一个json结果从mongodb返回每个元素的阵列 我想查询数组元素以找到一个特定的节点, 不使用ID或电子邮件作为过滤器仅将令牌编号作为过滤器(其唯一号码)

this is how one of the items json   looks like 
 {
"_id" : ObjectId("5cf67ad97739bfe8525e5353"),
"Email" : "eyal@gmail.com",
"Username" : "eyal",
"Password" : "1234",
"Tokens" : [ 
    {
        "Tokennumber" : "123",
        "Valid" : "true",
        "LoginDate" : ISODate("2019-06-04T00:00:00.000Z")
    }, 
    {
        "Tokennumber" : "124",
        "Valid" : "false",
        "LoginDate" : ISODate("2019-06-04T00:00:00.000Z")
    }, 
    {
        "Tokennumber" : "555",
        "Valid" : true,
        "LoginDate" : ISODate("2019-06-07T08:32:01.854Z")
    }

]
}
I would like to query the json using only one parameter  Tokennumber=555

令牌编号是一个唯一的数字,因此我需要通过他的Tokennumber查询

来获取整个节点
 the expected result would be the node 
 with this 
 data

"_id" : ObjectId("5cf67ad97739bfe8525e5353"),
"Email" : "eyal@gmail.com",
"Username" : "eyal",
"Password" : "1234",

推荐答案

以下Mongo查询使用$ Elemmatch

完成工作
db.User.aggregate({
    "$match": {
        "Tokens": {
            "$elemMatch": {
                "TokenNumber": "234"
            }
        }
    }
})

这是生成上述聚合管道的C#代码.它正在使用 mongodb.entities 这只是官方驾驶员的包装. [免责声明:我是作者]

using MongoDB.Entities;
using System.Linq;

namespace StackOverflow
{
    public class Program
    {
        public class User : Entity
        {
            public string Email { get; set; }
            public Token[] Tokens { get; set; }
        }

        public class Token
        {
            public string TokenNumber { get; set; }
            public bool Valid { get; set; }
        }

        static void Main(string[] args)
        {
            new DB("test");

            (new User
            {
                Email = "email@domain.com",
                Tokens = new[] {
                    new Token{ TokenNumber="123",Valid = false },
                    new Token{ TokenNumber="234",Valid = true },
                    new Token{ TokenNumber="456",Valid = false },
                }
            }).Save();

            var user = DB.Queryable<User>()
                         .Where(u => u.Tokens.Any(t => t.TokenNumber == "234"))
                         .Single();
        }
    }
}

编辑: 由于您提到您无法使用库,因此以下是如何与官方驱动程序进行操作:

var filter = Builders<User>.Filter
                           .ElemMatch(u => u.Tokens, 
                                      t => t.TokenNumber == "234");

var user = collection.Find(filter)
                     .Single();
var user = collection.Aggregate()
                     .Match(u => u.Tokens.Any(t => t.TokenNumber == "234"))
                     .ToList()
                     .Single();
var user = collection.AsQueryable()
                     .Where(u => u.Tokens.Any(t => t.TokenNumber == "234"))
                     .Single();

其他推荐答案

您可以使用过滤器访问节点类型.

例如:

var filter = Builders<YourObject>.Filter.Eq(x => x.Tokens.Any(t => t.Tokennumber == tokerNume), true);

var result = MongoContext.MongoDatabase.GetCollection<YourObject>("YourDocument").Find(filter).FirstOrDefault();

本文地址:https://www.itbaoku.cn/post/1557213.html

问题描述

I have a json result return from mongodb each element has array onside it I would like to query the array element to find a specific node , without using the id or email as filter only the token number as a filter (its a unique number)

this is how one of the items json   looks like 
 {
"_id" : ObjectId("5cf67ad97739bfe8525e5353"),
"Email" : "eyal@gmail.com",
"Username" : "eyal",
"Password" : "1234",
"Tokens" : [ 
    {
        "Tokennumber" : "123",
        "Valid" : "true",
        "LoginDate" : ISODate("2019-06-04T00:00:00.000Z")
    }, 
    {
        "Tokennumber" : "124",
        "Valid" : "false",
        "LoginDate" : ISODate("2019-06-04T00:00:00.000Z")
    }, 
    {
        "Tokennumber" : "555",
        "Valid" : true,
        "LoginDate" : ISODate("2019-06-07T08:32:01.854Z")
    }

]
}
I would like to query the json using only one parameter  Tokennumber=555

the token number is a unique number so i need to fetch the whole node by querying it by his Tokennumber

 the expected result would be the node 
 with this 
 data

"_id" : ObjectId("5cf67ad97739bfe8525e5353"),
"Email" : "eyal@gmail.com",
"Username" : "eyal",
"Password" : "1234",

推荐答案

the following mongo query get's the job done using $elemMatch

db.User.aggregate({
    "$match": {
        "Tokens": {
            "$elemMatch": {
                "TokenNumber": "234"
            }
        }
    }
})

here's the c# code that generated the above aggregation pipeline. it's using MongoDB.Entities which is just a wrapper for the official driver. [disclaimer: i'm the author]

using MongoDB.Entities;
using System.Linq;

namespace StackOverflow
{
    public class Program
    {
        public class User : Entity
        {
            public string Email { get; set; }
            public Token[] Tokens { get; set; }
        }

        public class Token
        {
            public string TokenNumber { get; set; }
            public bool Valid { get; set; }
        }

        static void Main(string[] args)
        {
            new DB("test");

            (new User
            {
                Email = "email@domain.com",
                Tokens = new[] {
                    new Token{ TokenNumber="123",Valid = false },
                    new Token{ TokenNumber="234",Valid = true },
                    new Token{ TokenNumber="456",Valid = false },
                }
            }).Save();

            var user = DB.Queryable<User>()
                         .Where(u => u.Tokens.Any(t => t.TokenNumber == "234"))
                         .Single();
        }
    }
}

EDIT: since you mentioned you are unable to use the library, the following would be how to do it with the official driver:

var filter = Builders<User>.Filter
                           .ElemMatch(u => u.Tokens, 
                                      t => t.TokenNumber == "234");

var user = collection.Find(filter)
                     .Single();
var user = collection.Aggregate()
                     .Match(u => u.Tokens.Any(t => t.TokenNumber == "234"))
                     .ToList()
                     .Single();
var user = collection.AsQueryable()
                     .Where(u => u.Tokens.Any(t => t.TokenNumber == "234"))
                     .Single();

其他推荐答案

You can access nodes types using filter.

e.g:

var filter = Builders<YourObject>.Filter.Eq(x => x.Tokens.Any(t => t.Tokennumber == tokerNume), true);

var result = MongoContext.MongoDatabase.GetCollection<YourObject>("YourDocument").Find(filter).FirstOrDefault();