private async Task RunExportSearch()

in src/Microsoft.Health.Fhir.Core/Features/Operations/Export/ExportJobTask.cs [274:358]


        private async Task RunExportSearch(
            ExportJobConfiguration exportJobConfiguration,
            ExportJobProgress progress,
            List<Tuple<string, string>> sharedQueryParametersList,
            CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(exportJobConfiguration, nameof(exportJobConfiguration));
            EnsureArg.IsNotNull(progress, nameof(progress));
            EnsureArg.IsNotNull(sharedQueryParametersList, nameof(sharedQueryParametersList));

            List<Tuple<string, string>> queryParametersList = new List<Tuple<string, string>>(sharedQueryParametersList);
            if (progress.ContinuationToken != null)
            {
                queryParametersList.Add(Tuple.Create(KnownQueryParameterNames.ContinuationToken, progress.ContinuationToken));
            }

            var requestedResourceTypes = _exportJobRecord.ResourceType?.Split(',');
            var filteredResources = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
            if (_exportJobRecord.Filters != null)
            {
                foreach (var filter in _exportJobRecord.Filters)
                {
                    filteredResources.Add(filter.ResourceType);
                }
            }

            IAnonymizer anonymizer = IsAnonymizedExportJob() ? await CreateAnonymizerAsync(cancellationToken) : null;

            if (progress.CurrentFilter != null)
            {
                await ProcessFilter(exportJobConfiguration, progress, queryParametersList, sharedQueryParametersList, anonymizer, "filter", cancellationToken);
            }

            if (_exportJobRecord.Filters != null && _exportJobRecord.Filters.Any(filter => !progress.CompletedFilters.Contains(filter)))
            {
                foreach (var filter in _exportJobRecord.Filters)
                {
                    if (!progress.CompletedFilters.Contains(filter) &&
                        requestedResourceTypes != null &&
                        requestedResourceTypes.Contains(filter.ResourceType, StringComparison.OrdinalIgnoreCase) &&
                        (_exportJobRecord.ExportType == ExportJobType.All || filter.ResourceType.Equals(KnownResourceTypes.Patient, StringComparison.OrdinalIgnoreCase)))
                    {
                        progress.SetFilter(filter);
                        await ProcessFilter(exportJobConfiguration, progress, queryParametersList, sharedQueryParametersList, anonymizer, "filter", cancellationToken);
                    }
                }
            }

            // The unfiltered search should be run if there were no filters specified, there were types requested that didn't have filters for them, or if a Patient/Group level export didn't have filters for Patients.
            // Examples:
            // If a patient/group export job with type and type filters is run, but patients aren't in the types requested, the search should be run here but no patients printed to the output
            // If a patient/group export job with type and type filters is run, and patients are in the types requested and filtered, the search should not be run as patients were searched above
            // If an export job with type and type filters is run, the search should not be run if all the types were searched above.
            if (_exportJobRecord.Filters == null ||
                _exportJobRecord.Filters.Count == 0 ||
                (_exportJobRecord.ExportType == ExportJobType.All &&
                !requestedResourceTypes.All(resourceType => filteredResources.Contains(resourceType))) ||
                ((_exportJobRecord.ExportType == ExportJobType.Patient || _exportJobRecord.ExportType == ExportJobType.Group) &&
                !filteredResources.Contains(KnownResourceTypes.Patient)))
            {
                if (_exportJobRecord.ExportType == ExportJobType.Patient)
                {
                    queryParametersList.Add(Tuple.Create(KnownQueryParameterNames.Type, KnownResourceTypes.Patient));
                }
                else if (_exportJobRecord.ExportType == ExportJobType.All && requestedResourceTypes != null)
                {
                    List<string> resources = new List<string>();

                    foreach (var resource in requestedResourceTypes)
                    {
                        if (!filteredResources.Contains(resource))
                        {
                            resources.Add(resource);
                        }
                    }

                    if (resources.Count > 0)
                    {
                        queryParametersList.Add(Tuple.Create(KnownQueryParameterNames.Type, resources.JoinByOrSeparator()));
                    }
                }

                await SearchWithFilter(exportJobConfiguration, progress, null, queryParametersList, sharedQueryParametersList, anonymizer, string.Empty, cancellationToken);
            }
        }