Here's a scheme of the structure of my Firestore database
Each company doc has a users collection
In my Flutter app, I need to retrieve a User document (like the one marked with the blue star). I know the id of this document, but I don't know under which company document it is located.
What's the fastest way to retrieve such document? Can I use .collectionGroup() and then filter the query by the doc id?
You can use collectionGroup() query with a where() clause.
Firestore.instance.collectionGroup('users').where('userIdField', isEqualTo: 'USER_ID')
You can read the user's company ID from the DocumentReference of that fetched document.
As #Frank commented, using where with document ID in a collection group query will not match. You would have to store user's UID as a field as well.
Related
I have recently started a firestore database. I was wondering is there any order in which the documents are added? is it just in the order they are created in?
There is no inherent sort order in which documents are stored, but you can specify the sort order you want to retrieve them in through the API. The documentation also contains a full table on how data is sorted.
If you're asking about the Firestore console, that by default orders the documents on their IDs, but you can change that by clicking the filter button at the top of the list of document IDs.
I am trying to think of a way to design the firestore db in a way that is efficient.
The main issue I am having with is how I should define "groups". Lets say a user is invited to a group chat and so the client needs to retrieve the data for that group chat, should I have a "groups" collection and then find the correct group document? OR, should I have a "groups" property in the user document that has a id to reference the group to retrieve?
In SQL, having a reference in a user's groups table would be the obvious answer, but I am not sure about firestore. I don't want to look through the entire collection of groups just to find the group that the user was newly invited in. Any tips? Also, my front end is in React and I am considering using the onSnapshot method to subscribe to the collection (that seems to be the best way to have real time updates).
What i believe is best for you is this :
First have a collection, suppose you make groups, and inside that every docuent has all the group unique ids,
And inside that for every group, i.e document, you can have a collection which holds all the chats for that group and group related info , like group type, etc etc
Hope it helps. feel free for doubts
First I want to say that the concept of a dedicated search engine is all new to me, so please be indulgent :-)
How does a transactional database entity with an Id and a Name does translate into an Azure Search Index field ?
Should we add only Name, or both Id and Name ?
For example, let's say I want the Client in my index.
I want both to search and have facets on Client.
Should I add only ClientName into the index ?
What if ClientName is renammed ?
What if ClientName is not unique ?
Should I add both fields into the index and have:
ClientName: Searchable
ClientId: Facetable, Filterable
I understand having ClientId Facetable (instead of ClientName) will make it more work to show the facets since i'll have to fetch myself the names corresponding the the ClientId returned by Azure Search.
Also, having the ClientId Filterable, I assume it would allow me to perform a batch rename of ClientName.
Is my reasoning ok ?
Is there any best practices / guidelines ?
EDIT
Here is a more concrete example.
Let say that in the transactional db, we have tables with Id and Name for Format, Location, Author, Genre, Region, ...
If we were to build those facets in Azure Search, would the recommended approach be to add both the Id and Name for each of them, and set the Id field as Facetable ?
It's probably a good idea to add both Id and Name, since potentially Name can change. Also, the Name field can contain arbitrary characters, while document id can only contain alphanumeric characters, dashes, underscores and equal signs (see Naming Rules).
Only id field must be unique (it has the same semantics as the primary key in a relational database). All other fields can have non-unique values. If a value changes, you just update the document (using merge or mergeOrUpload indexing action).
Azure Search supports batches of up to 1000 documents. If you want to update more documents than that, you'll have to break your updates into multiple batches. See Indexing API. The links shows REST API, but of course the same functionality is available in .NET SDK, if you're on .NET.
Should I add both fields into the index and have:
ClientName: Searchable
ClientId: Facetable, Filterable
I understand having ClientId Facetable (instead of ClientName) will make it more work to show the facets since i'll have to fetch myself the names corresponding the the ClientId returned by Azure Search.
We do not recommend making ClientId facetable. Facets work best on fields with a relatively small number of unique values. Since ClientId by definition must be unique, faceting will not be useful and any faceting queries that reference ClientId will probably perform poorly if you have many documents in your index. It is reasonable to make ClientId filterable though, since there may be situations when you want to retrieve or exclude certain documents by ClientId.
Also, having the ClientId Filterable, I assume it would allow me to perform a batch rename of ClientName.
This is not necessary. Making ClientId filterable allows you to filter by ClientId, nothing more. You always need to specify document IDs when updating fields using the Index API, but that doesn't require the ID field to be filterable.
I hope this gets you started, and as you have more specific questions, you can post them here.
I want to store urls in an index but I want unique url.
I'm making POST request to store my documents but I want to avoid duplicate document based on the url field.
Is there a way to specify a unique constraint on the url field ?
I have around 5 million of data so I don't want to make url as the document ID instead as it will slowdown my search query.
No, the _id is the only field that can have the uniqueness restriction. You probably know this but a new document with existing id would override the existing document with same id. You can use op_type=create or /my_index/my_type/ID/_create in order to get back an error if a document with same id already exists.
Hi I want to index a Solr Document and tag the document with multiple associated users. I want to enable searches like "give me the documents assocaited with userid 1000,1003...9300 containing the word X. More people will be added to the document during the lifetime of the document. I want to potentially associate thousands of users to one document. There is no need to show the associated users in the results, just for search, will indexing of userid or username be more performant and scalable. What field type would be more performant and scalable, appending to a text field, a multivalued field or any other approach?
I believe that using the userid (as an integer) would be the most performant. (At least from my experience so far). Also, using a multivalued field will allow you to use a filter query on the userid field to help improve the query response time.