【问题标题】:Passing variables into a string variable that contains json将变量传递给包含 json 的字符串变量
【发布时间】:2021-10-04 15:11:30
【问题描述】:

我正在尝试将查询的某些部分替换为具有特定值的变量。

例如,在我的变量 query 中,我想替换

  • \"level\": \"Information\"
  • \"match\": { \"level\": \"Error\"
  • 分别带有变量fieldName和变量fieldValue
    • fieldName 的值为 "_source.level"
    • fieldValue 的值分别为"information""error"

(不确定我是否必须创建另一个变量来保存 “错误”的第二个值,因为我想要信息和 错误。)

我遇到的问题通常是我知道你会在字符串之前添加一个$,并在你想要调用变量的地方添加一个{}。但是,当我在字符串的开头添加 $ 时,它不喜欢它并说

只有赋值、调用、递增、递减、等待和新对象表达式可以用作语句

所以我在试图弄清楚如何将这些变量传递给我的查询变量时遇到了问题。

string jsonFromFile;

using (var reader = new StreamReader(path))
{
    jsonFromFile = reader.ReadToEnd();
}

var json = JsonConvert.DeserializeObject<VirtualSupport>(jsonFromFile);


foreach (var item in json.Systems.Applications)
{
    foreach (var x in item.Application)
    {
        foreach (var y in x.BusinessProcessSteps)
        {
            foreach (var z in y.BusinessProcessStep.LogDataSources)
            {
                var fieldName = z.LogDataSource.LogFieldsMapping.LevelField.FieldName;
                var fieldValue = z.LogDataSource.LogFieldsMapping.LevelField.FieldValue;
            }
        }
    }
}

var query = "{\"size\": 1000,\"query\": {\"bool\": {\"should\":[ {\"match\": { \"level\": \"Information\" } }, {\"match\": { \"level\": \"Error\" } } ], " +
            "\"filter\": [ { \"range\": { \"@timestamp\": { \"gte\": \"2021-07-26T07:58:45.304-05:00\", \"lt\": \"2021-07-26T08:58:45.305-05:00\" } } } ]," +
            "\"minimum_should_match\": 1 } } }";

我正在读取并分配 fieldnamefieldvalue 的 json 文件的片段。

"LogFieldsMapping": {
    "IDField": { "FieldName": "_id" },
    "LevelField": {
        "FieldName": "_source.level",
        "FieldValue": [
            { "value": "Information" },
            { "value": "Error" }
        ]
    }
}

【问题讨论】:

    标签: c# elasticsearch json.net


    【解决方案1】:

    而不是使用$(字符串插值),您可以考虑将query-string 转换为一个类:

    {
        "size": 1000,
        "query": {
            "bool": {
                "should": [
                    {
                        "match": {
                            "level": "Information"
                        }
                    },
                    {
                        "match": {
                            "level": "Error"
                        }
                    }
                ],
                "filter": [
                    {
                        "range": {
                            "@timestamp": {
                                "gte": "2021-07-26T07:58:45.304-05:00",
                                "lt": "2021-07-26T08:58:45.305-05:00"
                            }
                        }
                    }
                ],
                "minimum_should_match": 1
            }
        }
    }
    

    可以转换成这样的:

    // Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); 
        public class Match
        {
            public string level { get; set; }
        }
    
        public class Should
        {
            public Match match { get; set; }
        }
    
        public class Timestamp
        {
            public DateTime gte { get; set; }
            public DateTime lt { get; set; }
        }
    
        public class Range
        {
            [JsonProperty("@timestamp")]
            public Timestamp Timestamp { get; set; }
        }
    
        public class Filter
        {
            public Range range { get; set; }
        }
    
        public class Bool
        {
            public List<Should> should { get; set; }
            public List<Filter> filter { get; set; }
            public int minimum_should_match { get; set; }
        }
    
        public class Query
        {
            public Bool @bool { get; set; }
        }
    
        public class Root
        {
            public int size { get; set; }
            public Query query { get; set; }
        }
    

    您可以从Root 实例化一个新对象,然后根据需要将任意数量的Matches 添加到Should,类似如下:

    using System;
    using System.Collections.Generic;
    using Newtonsoft.Json;
                        
    public class Program
    {
        public static void Main()
        {
            Root queryObject = new();
            queryObject.query.@bool.should.Add(
                new Should() {
                    match = new() {
                        level = "information"
                    }
                });
            queryObject.query.@bool.should.Add(
                new Should() {
                    match = new() {
                        level = "error"
                    }
                }
            );
            
            Console.WriteLine(JsonConvert.SerializeObject(queryObject));
    // Outputs: {"size":1000,"query":{"bool":{"should":[{"match":{"level":"information"}},{"match":{"level":"error"}}],"filter":null,"minimum_should_match":0}}}
        }
    }
    
    // Root myDeserializedClass = JsonConvert.DeserializeObject<Root>(myJsonResponse); 
        public class Match
        {
            public string level { get; set; }
        }
    
        public class Should
        {
            public Match match { get; set; }
        }
    
        public class Timestamp
        {
            public DateTime gte { get; set; }
            public DateTime lt { get; set; }
        }
    
        public class Range
        {
            [JsonProperty("@timestamp")]
            public Timestamp Timestamp { get; set; }
        }
    
        public class Filter
        {
            public Range range { get; set; }
        }
    
        public class Bool
        {
            public List<Should> should { get; set; }
            public List<Filter> filter { get; set; }
            public int minimum_should_match { get; set; }
        }
    
        public class Query
        {
            public Bool @bool { get; set; }
        }
    
        public class Root
        {
            public Root() 
            {
                size = 1000;
                query = new();
                query.@bool = new();
                query.@bool.should = new();
                // skipping the rest ...
            }
            
            public int size { get; set; }
            public Query query { get; set; }
        }
    

    https://dotnetfiddle.net/YhFM1I

    【讨论】:

    • 谢谢!问题是我需要使用 json 文件中包含 "level" 和 "information" 的属性。如果有帮助,我将添加 json 文件的 sn-p
    • 这里是一个通过你的属性循环的例子。基本原理是一样的,读取值并添加到Matches的List中:dotnetfiddle.net/yHTuvf
    猜你喜欢
    • 1970-01-01
    • 2011-08-21
    • 2011-04-03
    • 1970-01-01
    • 2020-06-16
    • 2015-06-15
    • 2019-12-04
    • 2018-04-01
    • 2022-11-27
    相关资源
    最近更新 更多