3using System.Globalization;
5using System.Reflection;
7using System.Threading.Tasks;
33 private static Dictionary<string, bool> stopWords =
new Dictionary<string, bool>();
35 private static Dictionary<string, CollectionInformation> collections;
36 private static Dictionary<string, IPersistentDictionary> indices;
37 private static Dictionary<Type, TypeInformation> types;
53 collections =
new Dictionary<string, CollectionInformation>();
54 indices =
new Dictionary<string, IPersistentDictionary>();
55 types =
new Dictionary<Type, TypeInformation>();
60 Database.ObjectInserted += this.Database_ObjectInserted;
61 Database.ObjectUpdated += this.Database_ObjectUpdated;
62 Database.ObjectDeleted += this.Database_ObjectDeleted;
63 Database.CollectionCleared += this.Database_CollectionCleared;
65 Types.OnInvalidated += this.Types_OnInvalidated;
73 Database.ObjectInserted -= this.Database_ObjectInserted;
74 Database.ObjectUpdated -= this.Database_ObjectUpdated;
75 Database.ObjectDeleted -= this.Database_ObjectDeleted;
76 Database.CollectionCleared -= this.Database_CollectionCleared;
78 Types.OnInvalidated -= this.Types_OnInvalidated;
82 await synchObj.BeginWrite();
88 if (!(indices is
null))
97 collectionInformation?.Dispose();
98 collectionInformation =
null;
100 collections?.Clear();
109 await synchObj.EndWrite();
116 Task.Run(() => this.ObjectInserted(e));
123 Tuple<CollectionInformation, TypeInformation, GenericObject> P = await Prepare(e.
Object);
128 if (ObjectId is
null)
132 TypeInformation TypeInfo = P.Item2;
139 IndexName = TypeInfo.GetIndexCollection(e.
Object);
148 if (Tokens is
null || Tokens.Length == 0)
153 await synchObj.BeginWrite();
156 ulong Index = await GetNextIndexNrLocked(IndexName);
160 IndexCollection = IndexName,
162 ObjectInstanceId = ObjectId,
165 Indexed = DateTime.UtcNow
168 await AddTokensToIndexLocked(Ref);
173 await synchObj.EndWrite();
186 private static async Task<IPersistentDictionary> GetIndexLocked(
string IndexCollection,
bool CreateIfNotFound)
191 if (CreateIfNotFound)
194 indices[IndexCollection] = Result;
202 DateTime TP = DateTime.UtcNow;
215 ObjectReferences =
new ulong[] { Ref.Index },
216 Counts =
new uint[] { (uint)Token.
DocIndex.Length },
217 Timestamps =
new DateTime[] { TP }
224 ulong[] NewReferences =
new ulong[c + 1];
225 uint[] NewCounts =
new uint[c + 1];
226 DateTime[] NewTimestamps =
new DateTime[c + 1];
228 Array.Copy(References.ObjectReferences, 0, NewReferences, 0, c);
229 Array.Copy(References.Counts, 0, NewCounts, 0, c);
230 Array.Copy(References.Timestamps, 0, NewTimestamps, 0, c);
232 NewReferences[c] = Ref.
Index;
233 NewCounts[c] = (uint)Token.
DocIndex.Length;
234 NewTimestamps[c] = TP;
236 References.ObjectReferences = NewReferences;
237 References.Counts = NewCounts;
238 References.Timestamps = NewTimestamps;
244 References.LastBlock++;
249 Counts = References.
Counts,
250 ObjectReferences = References.ObjectReferences,
251 Timestamps = References.Timestamps
254 await Index.
AddAsync(Token.
Token +
" " + References.LastBlock.ToString(), NewBlock,
true);
256 References.ObjectReferences =
new ulong[] { Ref.Index };
257 References.Counts =
new uint[] { (uint)Token.
DocIndex.Length };
258 References.Timestamps =
new DateTime[] { TP };
263 Token.Block = References.LastBlock + 1;
267 private static async Task<ulong> GetNextIndexNrLocked(
string IndexedCollection)
269 if (collectionInformation is
null)
272 string Key =
" C(" + IndexedCollection +
")";
273 KeyValuePair<bool, object> P = await collectionInformation.
TryGetValueAsync(Key);
275 if (!P.Key || !(P.Value is ulong Nr))
280 await collectionInformation.
AddAsync(Key, Nr,
true);
285 private static Task<CollectionInformation> GetCollectionInfoLocked(
string CollectionName,
bool CreateIfNotExists)
287 return GetCollectionInfoLocked(CollectionName, CollectionName, CreateIfNotExists);
290 private static async Task<CollectionInformation> GetCollectionInfoLocked(
291 string IndexCollectionName,
string CollectionName,
bool CreateIfNotExists)
293 if (collections is
null)
295 if (CreateIfNotExists)
296 throw new NotSupportedException(
"Service not initialized or shut down.");
304 KeyValuePair<bool, object> P = await collectionInformation.
TryGetValueAsync(CollectionName);
307 collections[CollectionName] = Result2;
311 if (!CreateIfNotExists)
315 collections[CollectionName] = Result;
316 await collectionInformation.
AddAsync(CollectionName, Result,
true);
327 Dictionary<string, ChunkedList<string>> ByIndex =
new Dictionary<string, ChunkedList<string>>();
329 await synchObj.BeginRead();
334 foreach (
object Obj
in Values)
338 !
string.IsNullOrEmpty(Info.IndexCollectionName))
343 ByIndex[Info.IndexCollectionName] = Collections;
346 Collections.Add(Info.CollectionName);
352 await synchObj.EndRead();
355 Dictionary<string, string[]> Result =
new Dictionary<string, string[]>();
358 Result[Rec.Key] = Rec.Value.ToArray();
371 await synchObj.BeginRead();
374 return await GetCollectionNamesLocked(IndexCollectionName);
378 await synchObj.EndRead();
388 private static async Task<string[]> GetCollectionNamesLocked(
string IndexCollectionName)
392 foreach (
object Obj
in await collectionInformation.
GetValuesAsync())
396 if (Info.IndexCollectionName == IndexCollectionName)
397 Result.
Add(Info.CollectionName);
410 internal static async Task<bool> SetFullTextSearchIndexCollection(
string IndexCollection,
string CollectionName)
412 await synchObj.BeginWrite();
421 Info = await GetCollectionInfoLocked(IndexCollection, CollectionName,
true);
428 Info.IndexCollectionName = IndexCollection;
438 await synchObj.EndWrite();
448 internal static async Task<bool> AddFullTextSearch(
string CollectionName, params
PropertyDefinition[] Properties)
450 await synchObj.BeginWrite();
465 await synchObj.EndWrite();
475 internal static async Task<bool> RemoveFullTextSearch(
string CollectionName, params
PropertyDefinition[] Properties)
477 await synchObj.BeginWrite();
492 await synchObj.EndWrite();
500 internal static async Task<Dictionary<string, PropertyDefinition[]>> GetFullTextSearchIndexedProperties()
502 Dictionary<string, PropertyDefinition[]> Result =
new Dictionary<string, PropertyDefinition[]>();
504 await synchObj.BeginRead();
507 foreach (
object Obj
in await collectionInformation.
GetValuesAsync())
515 await synchObj.EndRead();
526 internal static async Task<PropertyDefinition[]> GetFullTextSearchIndexedProperties(
string CollectionName)
528 await synchObj.BeginRead();
540 await synchObj.EndRead();
544 private static async Task<Tuple<CollectionInformation, TypeInformation, GenericObject>> Prepare(
object Object)
548 await synchObj.BeginWrite();
552 return await PrepareLocked(GenObj);
554 return await PrepareLocked(Object.GetType(), Object);
558 await synchObj.EndWrite();
562 private static async Task<Tuple<CollectionInformation, TypeInformation, GenericObject>> PrepareLocked(
GenericObject GenObj)
567 return new Tuple<CollectionInformation, TypeInformation, GenericObject>(CollectionInfo,
null, GenObj);
572 private static async Task<TypeInformation> GetTypeInfoLocked(Type T,
object Instance)
575 throw new Exception(
"Full text search module not started, or in the process of being stopped.");
577 if (types.TryGetValue(T, out TypeInformation Result))
580 TypeInfo TI = T.GetTypeInfo();
585 if (CollectionAttr is
null)
586 Result =
new TypeInformation(T, TI,
null,
null, CustomTokenizer,
null);
589 string CollectionName = CollectionAttr.Name;
590 bool DynamicIndex =
false;
593 if (!(SearchAttrs is
null))
609 IndexName = CollectionName;
619 Result =
new TypeInformation(T, TI, CollectionName, Info, CustomTokenizer, SearchAttrs);
622 await collectionInformation.
AddAsync(CollectionName, Info,
true);
625 Info.IndexForFullTextSearch =
true;
626 await collectionInformation.
AddAsync(CollectionName, Info,
true);
635 private static async Task<Tuple<CollectionInformation, TypeInformation, GenericObject>> PrepareLocked(Type T,
object Instance)
637 TypeInformation TypeInfo = await GetTypeInfoLocked(T, Instance);
638 if (!TypeInfo.HasCollection)
641 if (!TypeInfo.CollectionInformation?.IndexForFullTextSearch ??
false)
644 return new Tuple<CollectionInformation, TypeInformation, GenericObject>(TypeInfo.CollectionInformation, TypeInfo,
null);
655 internal static Keyword[] ParseKeywords(
string Search,
bool TreatKeywordsAsPrefixes)
657 return ParseKeywords(
Search, TreatKeywordsAsPrefixes,
true);
669 private static Keyword[] ParseKeywords(
string Search,
bool TreatKeywordsAsPrefixes,
673 StringBuilder sb =
new StringBuilder();
675 bool Required =
false;
676 bool Prohibited =
false;
677 string Wildcard =
null;
682 foreach (
char ch
in Search.ToLower().Normalize(NormalizationForm.FormD))
684 UnicodeCategory Category = CharUnicodeInfo.GetUnicodeCategory(ch);
685 if (Category == UnicodeCategory.NonSpacingMark)
688 if (
char.IsLetterOrDigit(ch))
702 Add(
new RegexKeyword(Token), Result, ref Required, ref Prohibited);
714 Token = sb.ToString();
720 Result, ref Required, ref Prohibited);
729 Token = sb.ToString();
735 Result, ref Required, ref Prohibited);
740 else if (Type == 0 && (ch ==
'*' || ch ==
'%' || ch ==
'¤' || ch ==
'#'))
744 Wildcard =
new string(ch, 1);
750 Token = sb.ToString();
759 else if (TreatKeywordsAsPrefixes)
764 Add(
Keyword, Result, ref Required, ref Prohibited);
780 else if (ch ==
'"' && ParseQuotes)
782 else if (ch ==
'\'' && ParseQuotes)
789 Token = sb.ToString();
796 if (TreatKeywordsAsPrefixes)
811 Add(
Keyword, Result, ref Required, ref Prohibited);
846 internal static async Task<T[]> FullTextSearch<T>(
string IndexCollection,
851 if (MaxCount <= 0 || Keywords is
null)
852 return Array.Empty<T>();
854 int NrKeywords = Keywords.Length;
856 return Array.Empty<T>();
858 Keywords = (
Keyword[])Keywords.Clone();
859 Array.Sort(Keywords, orderOfProcessing);
861 StringBuilder sb =
new StringBuilder();
863 sb.Append(IndexCollection);
865 sb.Append(Order.ToString());
876 string Key = sb.ToString();
880 if (queryCache.
TryGetValue(Key, out QueryRecord QueryRecord))
882 FoundReferences = QueryRecord.FoundReferences;
883 Process = QueryRecord.Process;
889 await synchObj.BeginRead();
892 Index = await GetIndexLocked(IndexCollection,
false);
894 if (!(Index is
null))
904 return Array.Empty<T>();
910 await synchObj.EndRead();
915 await synchObj.BeginWrite();
918 Index = await GetIndexLocked(IndexCollection,
true);
928 return Array.Empty<T>();
933 await synchObj.EndWrite();
946 Array.Sort(FoundReferences, relevanceOrder);
950 Array.Sort(FoundReferences, occurrencesOrder);
954 Array.Sort(FoundReferences, newestOrder);
958 Array.Sort(FoundReferences, oldestOrder);
962 queryCache[Key] =
new QueryRecord()
964 FoundReferences = FoundReferences,
1066 private class QueryRecord
1074 Task.Run(() => this.ObjectDeleted(e));
1081 Tuple<CollectionInformation, TypeInformation, GenericObject> P = await Prepare(e.
Object);
1086 if (ObjectId is
null)
1096 await synchObj.BeginWrite();
1099 await RemoveTokensFromIndexLocked(Ref);
1103 await synchObj.EndWrite();
1106 queryCache?.
Clear();
1110 catch (Exception ex)
1116 private static async Task RemoveTokensFromIndexLocked(
ObjectReference Ref)
1122 string Suffix =
" " + Token.
Block.ToString();
1131 int i = Array.IndexOf(References.ObjectReferences, Ref.
Index);
1135 int c = References.ObjectReferences.Length;
1136 ulong[] NewReferences =
new ulong[c - 1];
1137 uint[] NewCounts =
new uint[c - 1];
1138 DateTime[] NewTimestamps =
new DateTime[c - 1];
1142 Array.Copy(References.ObjectReferences, 0, NewReferences, 0, i);
1143 Array.Copy(References.Counts, 0, NewCounts, 0, i);
1144 Array.Copy(References.Timestamps, 0, NewTimestamps, 0, i);
1149 Array.Copy(References.ObjectReferences, i + 1, NewReferences, i, c - i - 1);
1150 Array.Copy(References.Counts, i + 1, NewCounts, i, c - i - 1);
1151 Array.Copy(References.Timestamps, i + 1, NewTimestamps, i, c - i - 1);
1154 References.ObjectReferences = NewReferences;
1155 References.Counts = NewCounts;
1156 References.Timestamps = NewTimestamps;
1175 Tuple<CollectionInformation, TypeInformation, GenericObject> P = await Prepare(Object);
1180 if (ObjectId is
null)
1184 TypeInformation TypeInfo = P.Item2;
1189 Tokens = await TypeInfo.Tokenize(Object, CollectionInfo.
Properties);
1197 if (AreSame(Tokens, Ref?.Tokens))
1202 await synchObj.BeginWrite();
1207 if (Tokens.Length == 0)
1213 IndexName = TypeInfo.GetIndexCollection(Object);
1217 ulong Index = await GetNextIndexNrLocked(IndexName);
1221 IndexCollection = IndexName,
1223 ObjectInstanceId = ObjectId,
1226 Indexed = DateTime.UtcNow
1229 await AddTokensToIndexLocked(Ref);
1236 await RemoveTokensFromIndexLocked(Ref);
1238 Ref.Tokens = Tokens;
1239 await AddTokensToIndexLocked(Ref);
1246 await synchObj.EndWrite();
1256 catch (Exception ex)
1264 int c = Tokens1?.Length ?? 0;
1265 int d = Tokens2?.Length ?? 0;
1272 for (i = 0; i < c; i++)
1274 if (!Tokens1[i].Equals(Tokens2[i]))
1285 IEnumerable<ObjectReference> ObjectsDeleted;
1294 await synchObj.BeginWrite();
1297 await RemoveTokensFromIndexLocked(Ref);
1301 await synchObj.EndWrite();
1309 while (!IsEmpty(ObjectsDeleted));
1311 catch (Exception ex)
1325 string[] Collections;
1327 await synchObj.BeginWrite();
1330 Index = await GetIndexLocked(IndexCollectionName,
true);
1333 Collections = await GetCollectionNamesLocked(IndexCollectionName);
1337 await synchObj.EndWrite();
1340 IEnumerable<ObjectReference> ObjectsDeleted;
1350 while (!IsEmpty(ObjectsDeleted));
1352 ReindexCollectionIteration Iteration =
new ReindexCollectionIteration();
1354 await
Database.Iterate(Iteration, Collections);
1356 return Iteration.NrObjectsProcessed;
1359 private static bool IsEmpty(IEnumerable<ObjectReference> Objects)
1369 public Task StartDatabase() => Task.CompletedTask;
1370 public Task EndDatabase() => Task.CompletedTask;
1371 public Task EndCollection() => Task.CompletedTask;
1372 public Task IncompatibleObject(
object ObjectId) => Task.CompletedTask;
1374 public long NrObjectsProcessed = 0;
1375 public int NrCollectionsProcessed = 0;
1377 public Task StartCollection(
string CollectionName)
1379 this.NrCollectionsProcessed++;
1380 return Task.CompletedTask;
1383 public async Task ProcessObject(
object Object)
1385 this.NrObjectsProcessed++;
1389 public Task ReportException(Exception Exception)
1392 return Task.CompletedTask;
1401 internal static void RegisterStopWords(params
string[] StopWords)
1403 Dictionary<string, bool> NewList =
new Dictionary<string, bool>();
1405 foreach (KeyValuePair<string, bool> P
in stopWords)
1406 NewList[P.Key] = P.Value;
1408 foreach (
string StopWord
in StopWords)
1409 NewList[StopWord] =
true;
1411 stopWords = NewList;
1419 internal static bool IsStopWord(
string StopWord)
1421 return stopWords.TryGetValue(StopWord, out
bool b) && b;
1431 public static async Task<TokenCount[]>
Tokenize(IEnumerable<object> Objects)
1446 public static async Task
Tokenize(IEnumerable<object> Objects,
1449 foreach (
object Object
in Objects)
1456 Type T = Object2.GetType();
1462 Found = tokenizers.TryGetValue(T, out Tokenizer);
1471 tokenizers[T] = Tokenizer;
1475 if (Tokenizer is
null)
1477 Tuple<CollectionInformation, TypeInformation, GenericObject> P = await Prepare(Object2);
1482 if (ObjectId is
null)
1486 TypeInformation TypeInfo = P.Item2;
1490 await TypeInfo.Tokenize(Object2, Process, CollectionInfo.
Properties);
1495 await Tokenizer.
Tokenize(Object2, Process);
1497 Process.DocumentIndexOffset++;
1501 private static readonly Dictionary<Type, ITokenizer> tokenizers =
new Dictionary<Type, ITokenizer>();
1503 private void Types_OnInvalidated(
object Sender, EventArgs e)
1557 Value = await Property.
GetValue(Obj);
1558 if (!(Value is
null))
1574 internal static async Task<FolderIndexationStatistics> IndexFolder(
string IndexCollection,
string Folder,
bool Recursive,
1575 params
string[] ExcludeSubfolders)
1577 if (
string.IsNullOrEmpty(IndexCollection))
1578 throw new ArgumentException(
"Empty index.", nameof(IndexCollection));
1580 if (
string.IsNullOrEmpty(Folder))
1581 throw new ArgumentException(
"Empty folder.", nameof(Folder));
1583 Folder = Path.GetFullPath(Folder);
1584 if (!Directory.Exists(Folder))
1585 throw new ArgumentException(
"Folder does not exist.", nameof(Folder));
1587 if (Folder[Folder.Length - 1] != Path.DirectorySeparatorChar)
1588 Folder += Path.DirectorySeparatorChar;
1590 string[] FileNames = Directory.GetFiles(Folder,
"*.*", Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
1591 Dictionary<CaseInsensitiveString, FileReference> References =
new Dictionary<CaseInsensitiveString, FileReference>();
1595 if (!(ExcludeSubfolders is
null))
1597 ExcludeSubfolders = (
string[])ExcludeSubfolders.Clone();
1598 c = ExcludeSubfolders.Length;
1600 for (i = 0; i < c; i++)
1602 ExcludeSubfolders[i] = Path.GetFullPath(ExcludeSubfolders[i]);
1603 d = ExcludeSubfolders[i].Length;
1605 if (d == 0 || ExcludeSubfolders[i][d - 1] != Path.DirectorySeparatorChar)
1606 ExcludeSubfolders[i] += Path.DirectorySeparatorChar;
1616 References[Reference.
FileName] = Reference;
1618 foreach (
string FileName
in FileNames)
1620 if (!(ExcludeSubfolders is
null))
1622 bool Exclude =
false;
1624 foreach (
string s
in ExcludeSubfolders)
1626 if (FileName.StartsWith(s))
1642 DateTime TP = File.GetLastWriteTimeUtc(FileName);
1644 if (References.TryGetValue(FileName, out
FileReference Ref))
1646 References.Remove(FileName);
1648 if (Ref.Timestamp == TP)
1661 FileName = FileName,
1662 IndexCollection = IndexCollection,
1689 internal static async Task<bool> IndexFile(
string IndexCollection,
string FileName)
1691 FileName = Path.GetFullPath(FileName);
1701 if (File.Exists(FileName))
1703 DateTime TP = File.GetLastWriteTimeUtc(FileName);
1705 if (ReferenceInDB is
null)
1709 FileName = FileName,
1710 IndexCollection = IndexCollection,
1723 ReferenceInDB.Timestamp = TP;
1729 else if (ReferenceInDB is
null)
Static class managing the application event log. Applications and services log events on this static ...
static void Exception(Exception Exception, string Object, string Actor, string EventId, EventLevel Level, string Facility, string Module, params KeyValuePair< string, object >[] Tags)
Logs an exception. Event type will be determined by the severity of the exception.
This attribute defines the name of the collection that will house objects of this type.
Event arguments for collection events.
string Collection
Collection
Static interface for database persistence. In order to work, a database provider has to be assigned t...
static Task< IEnumerable< object > > FindDelete(string Collection, params string[] SortOrder)
Finds objects in a given collection and deletes them in the same atomic operation.
static Task< IPersistentDictionary > GetDictionary(string Collection)
Gets a persistent dictionary containing objects in a collection.
static Task< object > TryGetObjectId(object Object)
Tries to get the Object ID of an object, if it exists.
static string WildcardToRegex(string s, string Wildcard)
Converts a wildcard string to a regular expression string.
static async Task Update(object Object)
Updates an object in the database.
static async Task Delete(object Object)
Deletes an object in the database.
static Task< IEnumerable< object > > Find(string Collection, params string[] SortOrder)
Finds objects in a given collection.
static async Task Insert(object Object)
Inserts an object into the default collection of the database.
static Task< object > TryLoadObject(string CollectionName, object ObjectId)
Tries to load an object given its Object ID ObjectId and its collection name CollectionName .
This filter selects objects that conform to all child-filters provided.
This filter selects objects that have a named field equal to a given value.
This filter selects objects that have a named field matching a given regular expression.
Contains information about a collection, in relation to full-text-search.
bool IndexForFullTextSearch
If collection should be indexed.
bool AddIndexableProperties(params PropertyDefinition[] Properties)
Adds properties for full-text-search indexation.
PropertyDefinition[] Properties
Properties to index
string CollectionName
Collection Name
string IndexCollectionName
Index Collection Name
bool RemoveIndexableProperties(params PropertyDefinition[] Properties)
Removes properties from full-text-search indexation.
Contains a reference to an indexed file.
DateTime Timestamp
When object was indexed.
CaseInsensitiveString FileName
Name of collection hosting object.
Contains statistics about a files folder (re)indexation procedure.
int TotalChanges
Total number of files changed in the index.
int NrDeleted
Number of files deleted from the index.
int NrUpdated
Number of files updated in the index.
int NrAdded
Number of files added to the index.
int NrFiles
Number of files processed.
This attribute defines that objects of this type should be indexed in the full-text-search index.
bool DynamicIndexCollection
If the index collection is dynamic (i.e. depends on object instance).
string GetIndexCollection(object Reference)
Name of full-text-search index collection.
Full-text search module, controlling the life-cycle of the full-text-search engine.
static async Task ProcessObjectUpdate(object Object)
Processes an object that has been updated.
static async Task< TokenCount[]> Tokenize(IEnumerable< object > Objects)
Tokenizes a set of objects using available tokenizers. Tokenizers are classes with a default contruct...
async Task Start()
Starts the module.
static async Task< long > ReindexCollection(string IndexCollectionName)
Reindexes the full-text-search index for a database collection.
static async Task< string[]> GetCollectionNames(string IndexCollectionName)
Gets the database collections that get indexed into a given index colltion.
async Task Stop()
Stops the module.
FullTextSearchModule()
Full-text search module, controlling the life-cycle of the full-text-search engine.
static async Task Tokenize(IEnumerable< object > Objects, TokenizationProcess Process)
Tokenizes a set of objects using available tokenizers. Tokenizers are classes with a default contruct...
static async Task< Dictionary< string, string[]> > GetCollectionNames()
Gets the database collections that get indexed into a given index colltion.
Abstract base class for keywords.
virtual async Task< bool > Process(SearchProcess Process)
Processes the keyword in a search process.
virtual bool Ignore
If keyword should be ignored.
abstract new string ToString()
Orders strings in descending length order
Represents a plain text keyword.
Represents a prohibited keyword.
Represents a wildcard keyword.
Represents a required keyword.
Contains information about a search process.
async Task< ObjectReference > TryGetObjectReference(ulong ObjectIndex, bool CanLoadFromDatabase)
Tries to get an object reference.
Dictionary< ulong, MatchInformation > ReferencesByObject
References found.
Represents a sequence of keywords.
Represents a wildcard keyword.
Event arguments for object reference events.
Contains a reference to an indexed object.
object ObjectInstanceId
Object ID of object instance.
TokenCount[] Tokens
Token count in document.
string Collection
Name of collection hosting object.
ObjectReference()
Contains a reference to an indexed object.
string IndexCollection
Collection of full-text-search index.
ulong Index
Reference number to use in full-text-index.
Contains matching information about a document in a search.
Orders entries from newest to oldest.
Orders entries based on occurrences of keywords.
Orders entries from oldest to newest.
Orders entries based on relevance.
Defines an indexable property.
async Task< object > GetValue(object Instance)
Gets the object to index.
Static class for access to Full-Text-Search
Represents a token and a corresponding occurrence count.
uint Block
Reference is stored in this block in the full-text-search index.
override string ToString()
Object.ToString()
uint[] DocIndex
Index inside document of each occurrence.
Contains a sequence of object references that include the token in its indexed text properties.
uint[] Counts
Token counts for respective object reference.
const int MaxReferences
Maximum amount of references in a block (100).
Tokenizes files via FileReference object references.
static bool HasTokenizer(string FileName)
Checks if a file has a file tokenizer associated with it.
Contains information about a tokenization process.
TokenCount[] ToArray()
Generates an array of token counts.
Event arguments for database object events.
Generic object. Contains a sequence of properties.
string CollectionName
Collection name.
Implements an in-memory cache.
void Dispose()
IDisposable.Dispose
bool TryGetValue(KeyType Key, out ValueType Value)
Tries to get a value from the cache.
void Clear()
Clears the cache.
A chunked list is a linked list of chunks of objects of type T .
bool HasFirstItem
If there is a first item in the collection
void Add(T Item)
Adds an item to the collection.
T[] ToArray()
Returns an array containing all elements of the collection.
Static class that dynamically manages types and interfaces available in the runtime environment.
Represents an object that allows single concurrent writers but multiple concurrent readers....
Base class for all nodes in a parsed script tree.
static async Task< object > WaitPossibleTask(object Result)
Waits for any asynchronous process to terminate.
Interface for full-text-search tokenizers
Task Tokenize(object Value, TokenizationProcess Process)
Tokenizes an object.
Persistent dictionary that can contain more entries than possible in the internal memory.
Task< KeyValuePair< bool, object > > TryGetValueAsync(string key)
Gets the value associated with the specified key.
Task< object[]> GetValuesAsync()
Gets all values.
Task AddAsync(string key, object value)
Adds an element with the provided key and value to the System.Collections.Generic....
Task ClearAsync()
Clears the dictionary.
Interface for iterations of database contents.
Interface for late-bound modules loaded at runtime.
FullTextSearchOrder
Order in which results are returned.
PaginationStrategy
How pagination in full-text-searches should be handled.