You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@chemistry.apache.org by Mark Streit <mc...@gmail.com> on 2012/09/10 20:20:03 UTC

How to iterate over an ItemIterable more than once

Hello

I am curious about how to get around something I've encountered using the
ItemIterable<QueryResult>

Using the OpenCMIS 0.8.0 SNAPSHOT, we've been able to successfully add
Documents and use CMIS SQL to retrieve the list of documents using the
IN_FOLDER predicate.  I am able to iterate over the list of QueryResult
objects just as the GettingStarted project shows without an issue.

However, I have a need to potentially "walk over the list" a *second
time*but notice that a 2nd read attempt gets skipped (it won't get
into the for
loop the SECOND time).  I looked to see if there was some method that can
be called to reset or re-position the iterator, finding something called
"skipTo(Long position).

The example below simply shows the same thing (similar to GettiingStarted)
 attempted twice in sequence just to prove to myself the behavior I was
seeing:

*The first for {} loops through and prints OK...*


Whereas the 2nd attempt (below) simply skips over the loop (same behavior
with and without use of skipTo() so I am assuming I am missing the intent
or I am using the wrong approach to reset...but I don't want to have to
make query calls to simply "reload" the result set.


There are only about 12 records returned in this use case but it could be
as high as 20 or 30.



            for (QueryResult qr : queryResult) {
               LOGGER.info("--------------------------------------------\n"
+ i + " , " +
qr.getPropertyByQueryName("cmis:objectTypeId").getFirstValue() + " , "
                     +
qr.getPropertyByQueryName("cmis:name").getFirstValue() + " , " +
qr.getPropertyByQueryName("cmis:createdBy").getFirstValue() + " , "
                     +
qr.getPropertyByQueryName("cmis:objectId").getFirstValue() + " , " +
qr.getPropertyByQueryName("cmis:contentStreamFileName").getFirstValue() + "
, "
                     +
qr.getPropertyByQueryName("acme:attachmentType").getFirstValue() + " , " +
qr.getPropertyByQueryName("cmis:contentStreamFileName").getFirstValue() + "
, "
                     +
qr.getPropertyByQueryName("cmis:contentStreamMimeType").getFirstValue() + "
, " +
qr.getPropertyByQueryName("cmis:contentStreamLength").getFirstValue());

               i++;

            }


            int i = 1;
            queryResult.skipTo(0);
            for (QueryResult qr : queryResult) {
               LOGGER.info("--------------------------------------------\n"
+ i + " , " +
qr.getPropertyByQueryName("cmis:objectTypeId").getFirstValue() + " , "
                     +
qr.getPropertyByQueryName("cmis:name").getFirstValue() + " , " +
qr.getPropertyByQueryName("cmis:createdBy").getFirstValue() + " , "
                     +
qr.getPropertyByQueryName("cmis:objectId").getFirstValue() + " , " +
qr.getPropertyByQueryName("cmis:contentStreamFileName").getFirstValue() + "
, "
                     +
qr.getPropertyByQueryName("acme:attachmentType").getFirstValue() + " , " +
qr.getPropertyByQueryName("cmis:contentStreamFileName").getFirstValue() + "
, "
                     +
qr.getPropertyByQueryName("cmis:contentStreamMimeType").getFirstValue() + "
, " +
qr.getPropertyByQueryName("cmis:contentStreamLength").getFirstValue());

               i++;


            }

Any insight would be appreciated.  I am sure I am doing something wrong.
FWIW, the back-end ECM product we are experimenting with is Alfreso 4
Community but I assume this is NOT product specific.

Thanks

Mark

Re: How to iterate over an ItemIterable more than once

Posted by Mark Streit <mc...@gmail.com>.
Florian

Thank you for the "rewind" suggestion - that WORKED.  Storing the
QueryResult objects back into a new List<QueryResult> while iterating
(initially) SOLVED the problem.

Appreciate your help.

On Mon, Sep 10, 2012 at 3:14 PM, Florian Müller <fm...@apache.org> wrote:

> Hi Mark,
>
> You cannot rewind an ItemIterable object. The skipTo() method returns a
> new ItemIterable object, which then starts at the provided position.
> Calling skipTo() does not change the state of the original object.
>
> But the new object will rerun the query. An ItemIterable object does not
> necessarily hold all results of a query. It fetches a batch of results and
> when this is consumed it fetched the next batch. This way it possible to
> process billions of query results without blowing up the repository or the
> client. You can control the batch size with an OperationContext (->
> setMaxItemsPerPage()).
>
> But that doesn't solve your problem. If you want to rewind, you have to
> store the query results in a List while you are iterating over the results
> for the first time.
>
>
> - Florian
>
>
>
>  Hello
>>
>> I am curious about how to get around something I've encountered using the
>> ItemIterable<QueryResult>
>>
>> Using the OpenCMIS 0.8.0 SNAPSHOT, we've been able to successfully add
>> Documents and use CMIS SQL to retrieve the list of documents using the
>> IN_FOLDER predicate.  I am able to iterate over the list of QueryResult
>> objects just as the GettingStarted project shows without an issue.
>>
>> However, I have a need to potentially "walk over the list" a *second
>> time*but notice that a 2nd read attempt gets skipped (it won't get
>>
>> into the for
>> loop the SECOND time).  I looked to see if there was some method that can
>> be called to reset or re-position the iterator, finding something called
>> "skipTo(Long position).
>>
>> The example below simply shows the same thing (similar to GettiingStarted)
>>   attempted twice in sequence just to prove to myself the behavior I was
>> seeing:
>>
>> *The first for {} loops through and prints OK...*
>>
>>
>>
>> Whereas the 2nd attempt (below) simply skips over the loop (same behavior
>> with and without use of skipTo() so I am assuming I am missing the intent
>> or I am using the wrong approach to reset...but I don't want to have to
>> make query calls to simply "reload" the result set.
>>
>>
>> There are only about 12 records returned in this use case but it could be
>> as high as 20 or 30.
>>
>>
>>
>>              for (QueryResult qr : queryResult) {
>>                 LOGGER.info("-----------------**
>> ---------------------------\n"
>> + i + " , " +
>> qr.getPropertyByQueryName("**cmis:objectTypeId").**getFirstValue() + " ,
>> "
>>                       +
>> qr.getPropertyByQueryName("**cmis:name").getFirstValue() + " , " +
>> qr.getPropertyByQueryName("**cmis:createdBy").**getFirstValue() + " , "
>>                       +
>> qr.getPropertyByQueryName("**cmis:objectId").getFirstValue(**) + " , " +
>> qr.getPropertyByQueryName("**cmis:contentStreamFileName").**getFirstValue()
>> + "
>> , "
>>                       +
>> qr.getPropertyByQueryName("**acme:attachmentType").**getFirstValue() + "
>> , " +
>> qr.getPropertyByQueryName("**cmis:contentStreamFileName").**getFirstValue()
>> + "
>> , "
>>                       +
>> qr.getPropertyByQueryName("**cmis:contentStreamMimeType").**getFirstValue()
>> + "
>> , " +
>> qr.getPropertyByQueryName("**cmis:contentStreamLength").**
>> getFirstValue());
>>
>>                 i++;
>>
>>              }
>>
>>
>>              int i = 1;
>>              queryResult.skipTo(0);
>>              for (QueryResult qr : queryResult) {
>>                 LOGGER.info("-----------------**
>> ---------------------------\n"
>> + i + " , " +
>> qr.getPropertyByQueryName("**cmis:objectTypeId").**getFirstValue() + " ,
>> "
>>                       +
>> qr.getPropertyByQueryName("**cmis:name").getFirstValue() + " , " +
>> qr.getPropertyByQueryName("**cmis:createdBy").**getFirstValue() + " , "
>>                       +
>> qr.getPropertyByQueryName("**cmis:objectId").getFirstValue(**) + " , " +
>> qr.getPropertyByQueryName("**cmis:contentStreamFileName").**getFirstValue()
>> + "
>> , "
>>                       +
>> qr.getPropertyByQueryName("**acme:attachmentType").**getFirstValue() + "
>> , " +
>> qr.getPropertyByQueryName("**cmis:contentStreamFileName").**getFirstValue()
>> + "
>> , "
>>                       +
>> qr.getPropertyByQueryName("**cmis:contentStreamMimeType").**getFirstValue()
>> + "
>> , " +
>> qr.getPropertyByQueryName("**cmis:contentStreamLength").**
>> getFirstValue());
>>
>>                 i++;
>>
>>
>>              }
>>
>> Any insight would be appreciated.  I am sure I am doing something wrong.
>> FWIW, the back-end ECM product we are experimenting with is Alfreso 4
>> Community but I assume this is NOT product specific.
>>
>> Thanks
>>
>> Mark
>>
>>


-- 
Mark
*
*

Re: How to iterate over an ItemIterable more than once

Posted by Florian Müller <fm...@apache.org>.
Hi Mark,

You cannot rewind an ItemIterable object. The skipTo() method returns a 
new ItemIterable object, which then starts at the provided position. 
Calling skipTo() does not change the state of the original object.

But the new object will rerun the query. An ItemIterable object does not 
necessarily hold all results of a query. It fetches a batch of results 
and when this is consumed it fetched the next batch. This way it 
possible to process billions of query results without blowing up the 
repository or the client. You can control the batch size with an 
OperationContext (-> setMaxItemsPerPage()).

But that doesn't solve your problem. If you want to rewind, you have to 
store the query results in a List while you are iterating over the 
results for the first time.


- Florian



> Hello
>
> I am curious about how to get around something I've encountered using the
> ItemIterable<QueryResult>
>
> Using the OpenCMIS 0.8.0 SNAPSHOT, we've been able to successfully add
> Documents and use CMIS SQL to retrieve the list of documents using the
> IN_FOLDER predicate.  I am able to iterate over the list of QueryResult
> objects just as the GettingStarted project shows without an issue.
>
> However, I have a need to potentially "walk over the list" a *second
> time*but notice that a 2nd read attempt gets skipped (it won't get
> into the for
> loop the SECOND time).  I looked to see if there was some method that can
> be called to reset or re-position the iterator, finding something called
> "skipTo(Long position).
>
> The example below simply shows the same thing (similar to GettiingStarted)
>   attempted twice in sequence just to prove to myself the behavior I was
> seeing:
>
> *The first for {} loops through and prints OK...*
>
>
> Whereas the 2nd attempt (below) simply skips over the loop (same behavior
> with and without use of skipTo() so I am assuming I am missing the intent
> or I am using the wrong approach to reset...but I don't want to have to
> make query calls to simply "reload" the result set.
>
>
> There are only about 12 records returned in this use case but it could be
> as high as 20 or 30.
>
>
>
>              for (QueryResult qr : queryResult) {
>                 LOGGER.info("--------------------------------------------\n"
> + i + " , " +
> qr.getPropertyByQueryName("cmis:objectTypeId").getFirstValue() + " , "
>                       +
> qr.getPropertyByQueryName("cmis:name").getFirstValue() + " , " +
> qr.getPropertyByQueryName("cmis:createdBy").getFirstValue() + " , "
>                       +
> qr.getPropertyByQueryName("cmis:objectId").getFirstValue() + " , " +
> qr.getPropertyByQueryName("cmis:contentStreamFileName").getFirstValue() + "
> , "
>                       +
> qr.getPropertyByQueryName("acme:attachmentType").getFirstValue() + " , " +
> qr.getPropertyByQueryName("cmis:contentStreamFileName").getFirstValue() + "
> , "
>                       +
> qr.getPropertyByQueryName("cmis:contentStreamMimeType").getFirstValue() + "
> , " +
> qr.getPropertyByQueryName("cmis:contentStreamLength").getFirstValue());
>
>                 i++;
>
>              }
>
>
>              int i = 1;
>              queryResult.skipTo(0);
>              for (QueryResult qr : queryResult) {
>                 LOGGER.info("--------------------------------------------\n"
> + i + " , " +
> qr.getPropertyByQueryName("cmis:objectTypeId").getFirstValue() + " , "
>                       +
> qr.getPropertyByQueryName("cmis:name").getFirstValue() + " , " +
> qr.getPropertyByQueryName("cmis:createdBy").getFirstValue() + " , "
>                       +
> qr.getPropertyByQueryName("cmis:objectId").getFirstValue() + " , " +
> qr.getPropertyByQueryName("cmis:contentStreamFileName").getFirstValue() + "
> , "
>                       +
> qr.getPropertyByQueryName("acme:attachmentType").getFirstValue() + " , " +
> qr.getPropertyByQueryName("cmis:contentStreamFileName").getFirstValue() + "
> , "
>                       +
> qr.getPropertyByQueryName("cmis:contentStreamMimeType").getFirstValue() + "
> , " +
> qr.getPropertyByQueryName("cmis:contentStreamLength").getFirstValue());
>
>                 i++;
>
>
>              }
>
> Any insight would be appreciated.  I am sure I am doing something wrong.
> FWIW, the back-end ECM product we are experimenting with is Alfreso 4
> Community but I assume this is NOT product specific.
>
> Thanks
>
> Mark
>