At the moment I'm getting Alfresco documents by queries like that:
select cmis:objectId from cmis:document ...
then I get the document itself by the following code:
String objectId = qresult.getPropertyValueByQueryName("d.cmis:objectId");
Document doc = (Document) session.getObject(session.createObjectId(objectId));
The problem is that when I get the document like that it seems to transfer the whole contentStream for every document which is not needed in my use-case.
Then I tried to get all properties by changing the query to:
select * from cmis:document
but this returns only the properties of the document aspect (cmis:name, ...).
Is it possible to get all properties of the document without having to add all aspect with a "join" to the query?
Or is there another way to get documents with all properties but without the contentstream?
Thanks in advance
getObject() does not transfer the content stream, only metadata.
You can control what is fetched from the repository with an Operation Context.
Related
I use this code to get a collection snapshot from Firestore.
firestore().collection('project').where('userID', '==', authStore.uid).onSnapshot(onResult, onError);
This returns a huge amount of data, but I only need a few fields. Is it possible to query only a specific field? For example, if I only need the projectName and the creationDate fields.
Is it possible to query only a specific field?
No, that is not possbile. A Firestore listener fires on the document level. This means that you'll always get the entire document.
For example if I only need the projectName and the creationDate fields.
You cannot only get the value of a specific set of fields. It's the entire document or nothing. If you, however, only need to read those values and nothing more, then you should consider storing them in a separate document. This practice is called denormalization, and it's a common practice when it comes to NoSQL databases.
You might also take into consideration using the Firebase Realtime Database, for the duplicated data.
Im trying to create one stream, that is using multiple documents references that are stored and fetched from Firebase Firestore.
Lets say I have two collection named users and documents. When user is created he gets document with his id in users collection with field named documentsHasAccessTo that is list of references to documents inside documents collection. It is important, that these documents can be located in different sub collections inside documents collection so I dont want to query whole documents and filter it, in order to save Firestore transfer and make it faster I already know paths to documents stored in documentsHasAccessTo field.
So for example, I can have user with data inside users/<user uid> document with documentsHasAccessTo field that stores 3 different document references.
I would like to achieve something like this (untested):
final userId = 'blablakfn1n21n4109';
final usersDocumentRef = FirebaseFirestore.instance.doc('users/$userId');
usersDocumentRef.snapshots().listen((snapshot) {
final references = snapshot.data()['documentsHasAccessTo'] as List<DocumentReference>;
final documentsStream = // create single query stream using all references from list
});
Keep in mind, that it would also be great, if this stream would update query if documentsHasAccessTo changes like in the example above, hence I used snapshots() on usersDocumentReferences rather than single get() fetch.
The more I think about this Im starting to believe this is simple impossible or theres a more simple and clean solution. Im open to anything.
You could use rxdart's switchMap and MergeStream:
usersDocumentRef.snapshots().switchMap((snapshot) {
final references = snapshot.data()['documentsHasAccessTo'] as List<DocumentReference>;
return MergeStream(references.map(ref) => /* do something that creates a stream */));
});
I want to do something like:
final collectionReference = Firestore.instance.collection('myCollection');
final List<String> documentList = collectionReference.getDocList();
OR
final query = collectionReference.orderBy('lastUpdated', descending: true).limit(100);
final List<String> documentList = query.getDocList();
Currently when we use get() or query.getDocuments() it will return the whole Document list and all contents along with it. But you know that we wanna optimize reads thus we make use of the 1MiB limit of each Documents. Thus we don't wanna download the whole document's contents. Rather we just need the IDs for other usage. Is there a way to do this ?
Thanks
There no way to do this with the Flutter APIs (or any of the web or mobile clients).
The only way is with backend code, where you have a method like select() (link to the nodejs API) on Query that lets you select which document fields to return. So, you could have your app call a backend to return the document IDs, but not directly in the app.
If you must query from the client, consider moving fields unnecessary for queries to documents in anther collection with the same IDs, and request them only when needed.
So this is possible:
const docSnapshot = await firebase.firestore().collection("SOME_COL").doc("SOME_DOC").get();
console.log(docSnapshot.exists);
But it "downloads" the whole document just to check if it exists. And I'm currently working with some havier documents and I have a script where I just need to know if they exist, but I don't need to download them at that time.
Is there a way to check if a document exist without .get() and avoid downloading the document data?
It seems you are using the JavaScript SDK. With this SDK there isn't any way to only get a subset of the fields of a document.
One of the possible solutions is to maintain another collection with documents that have the same IDs than the main collection documents but which only hold a very small dummy field. You could use a set of Cloud Functions to synchronise the two collections (Documents creation/deletion).
On the other hand, with the Firestore REST API, it is possible, with the get method, to define a DocumentMask which defines a "set of field paths on a document" and is "used to restrict a get operation on a document to a subset of its fields". Depending on your exact use case, this can be an interesting and easier solution.
I Want to retrieve All document content from alfresco repository. So can anyone help me that how can i traverse the repository using CMIS. And while traversing i also want to separate the documents based on its type.
At this moment i am able to get any one document by specifying the path. but now my requirement is to traverse whole repository and get all the documents.
So can any one help me with this.
Also suggest me that "Traversal of all folders and later separate by specific type" will be the good approach OR "Search specific type of document using CMIS query" will be the good approach.
Thanks in Advance.
Yagami's answer is a good start, but there are a few things to add.
First, do not do "select *" unless you actually need every single property the repository has. That is a potential performance problem. Only ask for what you need.
Second, one of your comments talks about segmenting results by type. In CMIS, a type is kind of like a SQL table. So in your case, you would do three different queries using each of your three custom types as a different type in the from clause:
select * from test:mainContract;
select * from test:subContract;
select * from test:royaltyStatement;
Finally, unless you have just a handful of documents in your repository, you are almost certainly going to want to use a paged result set. Otherwise, you will only get back the maximum number of results the server is configured to return. That may not be large enough to get the entire set.
For an example showing paging the result set, see Apache CMIS: Paging query result
To perform an action like this (getting all the document content) you need to follow this steps
Step 1 : Create a saver Class
What i mean with sever class, it will hold two information (for me it's the most valuable informations) the two of them most be character varying
1 - The document ID
2 - The document Name
Step 2 : Get all the document
To get all the document we have to use a query
String query;
query = "SELECT * FROM cmis:document ";
You will get all the document that you have in your repository.
You can add some condition to make your research more easier like in this example :
query = "SELECT * FROM cmis:document WHERE IN_FOLDER('" + folderId + "')";
In this example you will get document of a particular folder.
ItemIterable<QueryResult> resultList = session.query(query, false);
and finally
for (QueryResult qr : resultList) {
String idDocument = qr.getPropertyByQueryName("cmis:objectId").getFirstValue().toString();
String name = qr.getPropertyByQueryName("cmis:name").getFirstValue().toString();
Document doc = (Document) session.getObject(idDocument);// this is how you can get document with add that's mean no need of path
}
You can read more about query in CMIS query.
Step 3 : Save every time the information in the saver class
I think it's clear that you have to save every time you use the loop (in step 2) in an occurence of saver class.
I hope that helped you.