Exemple #1
0
        public static ObjectSearchResults SearchObjects(Vault vault, int objType,
                                                        int?classId, SearchConditions otherConditions, bool deleted = false)
        {
            var scs = otherConditions != null?otherConditions.Clone() : new SearchConditions();

            AddBaseConditions(scs, objType, classId, deleted);
            return(vault.ObjectSearchOperations.SearchForObjectsByConditionsEx(
                       scs, MFSearchFlags.MFSearchFlagNone, false, 0, 0));
        }
Exemple #2
0
        /// <summary>
        /// Returns whether there are objects in the vault that have a higher internal Id than
        /// the current segment.
        /// </summary>
        /// <param name="vaultObjectSearchOperations">The search operations object to query with.</param>
        /// <param name="searchConditions">The search conditions to execute.</param>
        /// <param name="searchFlags">Any search flags to execute (note that the order will not be respected).</param>
        /// <param name="segment">The zero-based index of the segment to return data for.</param>
        /// <param name="itemsPerSegment">The number of items to include in each segment. See <see cref="DefaultNumberOfItemsInSegment"/>.</param>
        /// <returns>true if there is at least one, false if there are none.</returns>
        private static bool HasMoreResults(this IVaultObjectSearchOperations vaultObjectSearchOperations,
                                           SearchConditions searchConditions,
                                           int segment,
                                           MFSearchFlags searchFlags = MFSearchFlags.MFSearchFlagDisableRelevancyRanking,
                                           int itemsPerSegment       = IVaultObjectSearchOperationsExtensionMethods.DefaultNumberOfItemsInSegment)
        {
            // Sanity.
            if (null == vaultObjectSearchOperations)
            {
                throw new ArgumentNullException(nameof(vaultObjectSearchOperations));
            }
            if (null == searchConditions)
            {
                throw new ArgumentNullException(nameof(searchConditions));
            }
            if (segment <= 0)
            {
                segment = 0;
            }
            if (itemsPerSegment <= 0)
            {
                itemsPerSegment = IVaultObjectSearchOperationsExtensionMethods.DefaultNumberOfItemsInSegment;
            }

            // There are more results if there are any objects that meet the search criteria, with
            // an Id greater than the current segment range.

            // Clone the search conditions (so we can add object id condition).
            var internalSearchConditions = searchConditions.Clone();

            // Add search condition:
            //   Id at least (segment * itemsPerSegment)
            internalSearchConditions.AddMinimumObjectIdSearchCondition(segment * itemsPerSegment);

            // If we get zero items then there are no more results.
            var results = vaultObjectSearchOperations.SearchForObjectsByConditionsEx(
                internalSearchConditions,          // Our search conditions.
                searchFlags,
                SortResults: false,                // Don't bother attempting to sort them.
                MaxResultCount: 1,                 // We only need to know if there is at least one, nothing more.
                SearchTimeoutInSeconds: 0);

            // Did we only get one?
            return(0 != results.Count);
        }
Exemple #3
0
        private static ObjectVersions SearchObjectsByClass(Vault vault, int classId, SearchConditions searchConditions = null)
        {
            SearchConditions scs = searchConditions == null ? new SearchConditions() : searchConditions.Clone();
            //对象类别
            var conditionClass = new SearchCondition();

            conditionClass.ConditionType = MFConditionType.MFConditionTypeEqual;
            conditionClass.Expression.DataPropertyValuePropertyDef = 100;
            conditionClass.TypedValue.SetValue(MFDataType.MFDatatypeLookup, classId);
            scs.Add(-1, conditionClass);
            //是否删除
            var conditionDeleted = new SearchCondition();

            conditionDeleted.ConditionType = MFConditionType.MFConditionTypeEqual;
            conditionDeleted.Expression.DataStatusValueType = MFStatusType.MFStatusTypeDeleted;
            conditionDeleted.TypedValue.SetValue(MFDataType.MFDatatypeBoolean, false);
            scs.Add(-1, conditionDeleted);
            var sResults = vault.ObjectSearchOperations.SearchForObjectsByConditionsEx(scs, MFSearchFlags.MFSearchFlagNone, false, 0, 0);

            return(sResults.GetAsObjectVersions());
        }
Exemple #4
0
        /// <summary>
        /// Searches for objects matching the search conditions, in segments by M-Files Object Id.
        /// Returns an enumerable of each segment's search results.
        /// Using this approach (e.g. searching for IDs 1-1000, then 1001-2000, etc.) bypasses the return count limitations.
        /// </summary>
        /// <param name="vaultObjectSearchOperations">The search operations object to query with.</param>
        /// <param name="searchConditions">The search conditions to execute.</param>
        /// <param name="searchFlags">Any search flags to execute (note that the order will not be respected).</param>
        /// <param name="startSegment">The (zero-based) index of the segment to start at.</param>
        /// <param name="itemsPerSegment">The number of items to include in each segment. See <see cref="DefaultNumberOfItemsInSegment"/>.</param>
        /// <param name="maximumSegmentIndex"></param>
        /// <returns></returns>
        /// <remarks>Be aware that calling this method will return all matching items, which may cause significant load on the M-Files server.</remarks>
        public static IEnumerable <IObjectSearchResults> SearchForObjectsByConditionsSegmented(this IVaultObjectSearchOperations vaultObjectSearchOperations,
                                                                                               SearchConditions searchConditions,
                                                                                               MFSearchFlags searchFlags = MFSearchFlags.MFSearchFlagDisableRelevancyRanking,
                                                                                               int startSegment          = 0,
                                                                                               int itemsPerSegment       = IVaultObjectSearchOperationsExtensionMethods.DefaultNumberOfItemsInSegment,
                                                                                               int maximumSegmentIndex   = IVaultObjectSearchOperationsExtensionMethods.MaximumSegmentIndex)
        {
            // Sanity.
            if (null == searchConditions)
            {
                throw new ArgumentNullException(nameof(searchConditions));
            }
            if (null == vaultObjectSearchOperations)
            {
                throw new ArgumentNullException(nameof(vaultObjectSearchOperations));
            }
            if (startSegment < 0)
            {
                startSegment = IVaultObjectSearchOperationsExtensionMethods.DefaultNumberOfItemsInSegment;
            }
            if (maximumSegmentIndex < 0)
            {
                maximumSegmentIndex = IVaultObjectSearchOperationsExtensionMethods.MaximumSegmentIndex;
            }

            // No point having relevancy ranking as we're throwing it away.
            // ReSharper disable once BitwiseOperatorOnEnumWithoutFlags
            searchFlags = searchFlags | MFSearchFlags.MFSearchFlagDisableRelevancyRanking;

            // A segment has a start index and a number of items in it.
            // Segment 0 = object Ids 0 through 999.
            // Segment 1 = object Ids 1000 through 1999.
            // ....

            // Start at segment zero.
            int segment = startSegment;

            // Let's have a sanity counter, just in case.
            int sanity = maximumSegmentIndex;

            // While there are objects with a higher ID than the segment we're in, continue searching.
            while ((sanity > 0) && vaultObjectSearchOperations.HasMoreResults(searchConditions, segment, searchFlags, itemsPerSegment))
            {
                // Clone the search conditions (so we can add current-segment condition).
                var internalSearchConditions = searchConditions.Clone();

                // Add search condition:
                //   Id within the range: (segment - itemsPerSegment) to ((segment + 1) * itemsPerSegment)
                internalSearchConditions.AddObjectIdSegmentSearchCondition(segment, itemsPerSegment);

                // Return the results.
                yield return(vaultObjectSearchOperations
                             .SearchForObjectsByConditionsEx(internalSearchConditions, searchFlags, SortResults: false, MaxResultCount: 0,
                                                             SearchTimeoutInSeconds: 0));

                // Move to the next segment.
                segment++;

                // Reduce the sanity value (if we hit zero we will exit).
                sanity--;
            }
        }
Exemple #5
0
        /// <summary>
        /// Executes a segmented search using the API directly.
        /// </summary>
        static void UseApiDirectly()
        {
            // Connect to the server (localhost, tcp, current Windows user).
            var application = new MFilesServerApplication();

            application.ConnectAdministrative();

            // Get a connection to the vault.
            var vault = application.LogInToVault(Program.sampleVaultGuid.ToString("B"));

            // Load the object types from the vault.
            Console.WriteLine("Loading object types...");
            var objectTypes = vault
                              .ObjectTypeOperations
                              .GetObjectTypes()
                              .Cast <ObjType>()
                              .ToList();

            Console.WriteLine($"Iterating over {objectTypes.Count} object types...");

            // Iterate over the object types to count the objects.
            foreach (var objectType in objectTypes)
            {
                // Create the basic search conditions collection.
                var searchConditions = new SearchConditions();

                // Add a condition for the object type we're interested in.
                {
                    // Create the search condition (for object type id).
                    SearchCondition condition = new SearchCondition
                    {
                        ConditionType = MFConditionType.MFConditionTypeEqual
                    };
                    condition.Expression.SetStatusValueExpression(MFStatusType.MFStatusTypeObjectTypeID, null);
                    condition.TypedValue.SetValue(MFDataType.MFDatatypeLookup, objectType.ID);

                    // Add the condition at the index provided.
                    searchConditions.Add(-1, condition);
                }

                // Create variables for the segment information.
                const int itemsPerSegment       = 1000; // Maximum number of items in each segment.
                var       segment               = 0;    // Start; this will increment as we go.
                var       moreItems             = true; // Whether there are more items to load.
                var       countIncludingDeleted = 0;    // The count of matching items.

                // Whilst there are items in the results, we need to loop.
                while (moreItems)
                {
                    // Execute a search within the object id segment.
                    {
                        // Clone the search conditions (so we can add current-segment condition).
                        var internalSearchConditions = searchConditions.Clone();

                        // Add search condition:
                        //   Id within the range: (segment - itemsPerSegment) to ((segment + 1) * itemsPerSegment)
                        {
                            // Create the search condition.
                            SearchCondition condition = new SearchCondition
                            {
                                ConditionType = MFConditionType.MFConditionTypeEqual
                            };
                            condition.Expression.SetObjectIDSegmentExpression(itemsPerSegment);
                            condition.TypedValue.SetValue(MFDataType.MFDatatypeInteger, segment);

                            // Add the condition at the index provided.
                            internalSearchConditions.Add(-1, condition);
                        }

                        // Execute the search and increment the count.
                        countIncludingDeleted += vault.ObjectSearchOperations
                                                 .SearchForObjectsByConditionsEx(internalSearchConditions, MFSearchFlags.MFSearchFlagDisableRelevancyRanking,
                                                                                 SortResults: false, MaxResultCount: 0,
                                                                                 SearchTimeoutInSeconds: 0).Count;

                        // Move to the next segment.
                        segment++;
                    }

                    // Are there any more items?
                    {
                        // Clone the search conditions (so we can add object id condition).
                        var internalSearchConditions = searchConditions.Clone();

                        // Add search condition:
                        //   Id at least (segment * itemsPerSegment)
                        {
                            // Create the search condition.
                            SearchCondition condition = new SearchCondition
                            {
                                ConditionType = MFConditionType.MFConditionTypeGreaterThanOrEqual
                            };
                            condition.Expression.SetStatusValueExpression(MFStatusType.MFStatusTypeObjectID, null);
                            condition.TypedValue.SetValue(MFDataType.MFDatatypeInteger, segment * itemsPerSegment);

                            // Add the condition at the index provided.
                            internalSearchConditions.Add(-1, condition);
                        }

                        // If we get one item then there's more results.
                        moreItems = 1 == vault.ObjectSearchOperations.SearchForObjectsByConditionsEx(
                            internalSearchConditions,                      // Our search conditions.
                            MFSearchFlags.MFSearchFlagDisableRelevancyRanking,
                            SortResults: false,                            // Don't bother attempting to sort them.
                            MaxResultCount: 1,                             // We only need to know if there is at least one, nothing more.
                            SearchTimeoutInSeconds: 0).Count;
                    }
                }

                // Output the stats.
                Console.WriteLine($"\t{objectType.NamePlural}:");
                Console.WriteLine($"\t\tTotal: {countIncludingDeleted} (included deleted)");
            }

            Console.WriteLine($"Complete.");

            // Disconnect.
            vault.LogOutSilent();
            application.Disconnect();
        }