using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using System.Threading; using LuhnNet; using Newtonsoft.Json; //Do not remove - Required for JObject using Newtonsoft.Json.Linq; using Shinydocs.CognitiveToolkit.Scripting; using Shinydocs.CognitiveToolkit.Core.Models.Index; using Shinydocs.CognitiveToolkit.Core.Tools.ScrollTools.RunScript; using Shinydocs.CognitiveToolkit.UI.CommandLine; using Shinydocs.CognitiveToolkit.UI.CommandLine.Progress; using Shinydocs.CognitiveToolkit.Utilities; //Do not remove - Required for JObject #pragma warning disable CS8603 #pragma warning disable CS8619 #pragma warning disable CS8604 #pragma warning disable CS8600 #pragma warning disable CS8601 #pragma warning disable CS8618 public class ExportUniqueValues : IScript { // ScriptLogger allows you to log to the same index as the rest of the cognitive toolkit. // See https://github.com/serilog/serilog/wiki/Writing-Log-Events for message formatting information private readonly ScriptLogger _log = new ScriptLogger(); private static string ScriptName = "ExportUniqueValues"; private static string Version = "1.0.0.1"; private string _indexName; private string _query = string.Empty; private string[] _fieldsToReturn = {"id"}; private string _serverUrl; public string _fieldName; public string _output; private List _uniqueValues = new List(); private RunScriptDocumentUpdater _documentUpdater; private int _threads; private int _nodesPerRequest; public void SetUp(string[] arguments){ _log.Information(string.Format("{0} version {1}", ScriptName, Version)); Console.WriteLine(string.Format("{0} version {1}", ScriptName, Version)); try { Dictionary options; // OptionsParser will parse an array of arguments into a dictionary of flags and values if (OptionsParser.TryParse(arguments, out options)) { OptionsParser.ParseStandardOptions(options, out _serverUrl, out _indexName, out _threads, out _nodesPerRequest); OptionsParser.ParseQueryOption(options, out _query); if (!options.TryGetValue("--field-name", out _fieldName)) OptionsParser.InputError("The field name (--field-name) is a required parameter."); if (!options.TryGetValue("--output-file", out _output)) _output = "UniqueValues.txt"; _fieldsToReturn = _fieldsToReturn.Append(_fieldName).ToArray(); _documentUpdater = new RunScriptDocumentUpdater(_serverUrl, _indexName, _fieldsToReturn, _nodesPerRequest, _threads); } else { throw new ArgumentException("Failed to parse arguments. Tool requires exactly the following parameters -q (Query or Path to QueryFile) -u (Index Server Url) -i (IndexName) --field-name."); } } catch (Exception ex) { var message = ex.Message + "\n\nPlease review the following parameters:" + "\n" + "-q \tquery or path to queryfile" + "\n" + "-u \tindex server URL" + "\n" + "-i \tindex name" + "\n" + "--field-name \tfield name" + "\n" + "--output-file" + "\n" + "--threads (Default: 1)" + "\n" + "--nodes-per-request (Default: 100)"; _log.Error(ex, message); Console.WriteLine(message); throw; } } public void Run() { var processedTotal = 0; var updatedTotal = 0; using (var progress = new CommandLineProgress()) { _documentUpdater.Progress = progress; _documentUpdater.Update(_query,document => { // Check if the value is an array or a single value var value = document[_fieldName]; Interlocked.Increment(ref processedTotal); if (value is JArray) { // If it's an array, process each item foreach (string item in ((JArray)value).ToObject()) { if (!string.IsNullOrEmpty(item) && !_uniqueValues.Contains(item)) { _uniqueValues.Add(item); Interlocked.Increment(ref updatedTotal); } } } else { string stringValue = value?.ToString() ?? string.Empty; if (!string.IsNullOrEmpty(stringValue) && !_uniqueValues.Contains(stringValue)) { _uniqueValues.Add(stringValue); Interlocked.Increment(ref updatedTotal); } } RunScriptDocumentUpdater.TotalProcessed = processedTotal; return new Dictionary(); }); } } public void TearDown() { string filePath = _output; JArray jsonArray = new JArray(); // Add each unique value to the JArray foreach (var value in _uniqueValues) { jsonArray.Add(value); } // Serialize the JArray to a JSON string string jsonString = JsonConvert.SerializeObject(jsonArray, Formatting.Indented); // Write the JSON string to a file File.WriteAllText(filePath, jsonString); } }