What is the limit of nested OR's in a CAML Query? - sharepoint

From the question 'SQL IN equivalent in CAML' I learned that SharePoint 2010 has a SQL "IN" equivalent for CAML. Also that the 2007 version does not support this. The OP solved this by nesting a bunch of OR statements to achieve the same result. I tested this and the nesting indeed does the magic, but...
In my case I'm getting items from a list with around a 1000 items. I dynamically create a statement with all the IDs in nested OR-blocks for my CAML-query. I didn't worry about the big number of nested blocks as this is what MSDN states about the OR-element:
Occurrences: Minimum: 0, Maximum: Unbounded.
and:
This element can be nested inside other Or and And elements. The server supports unlimited complicated queries.
When I call the GetListItems-method from the SharePoint 2007 built-in webservice, I get following error:
Exception of type 'Microsoft.SharePoint.SoapServer.SoapServerException' was thrown. Some part of your SQL statement is nested too deeply. Rewrite the query or break it up into smaller queries.
My code is written correctly because I tested the same code with only 5 nested Or-elements and the result is as expected. My question is: what IS the limit of nested Or-elements? I cannot find this anywhere as Microsoft claims this is unlimited.
Thanks in advance!

For those facing the same problem. I went for a search on SharePoint.StackExchange.com and found the following question:
Nested CAML Query results in exception “ Some part of your SQL statement is nested too deeply. Rewrite the query or break it up into smaller queries”
One of the answers points to this website:
CAML: Nested Too Deep
The person discovered that 500 items was too much but that a batch of 300 worked fine. So I tried this and this also works for me. So for anyone that faces the same problem, this might be the solution. :)

Same problem with SP2010 and nested ORs, breaks when reaching 160+ nested items.
Error raised is not very helpful (System.ArgumentException) when trying to get the SPListItemCollection = List.GetItems(Query);
Looks like SQL server refuse to execute the query.
Solution is to break in multiple queries or change the way of querying.

Related

Sitecore fast query does not return values

I have used Sitecore fast query in my C# code to get items and sub items which are matching with the criteria. But fast query does not returning any items though there are.
My fast query is like below;
fast:/sitecore/content/...//*[#__Workflow state='{item id}']
This will return no items, but removing fast: from the query will return the items by taking more time.
I tried escaping spaces in the query path as well like below, but it didn't work;
fast:/sitecore/content/...//*[##__Workflow state#='{item id}']
Are there any way to get sub items with a filtration using fast query?
I noticed you use theee dots in your query, which is not correct. You can use 2 dots to sleect the parent item, but in your query selecting the parent from /sitecore/content seems a bit odd.
It seems you can do with this query:
fast:/sitecore/content//*[#__Workflow state='{item id}']
See also this document for the syntax and examples and the limitations of using fast-query instead normal query
EDIT:
Sitecore Fast query does not account for the context language (results include items with versions that match the query in any language). I just did a quick test in the Developer Center in Sitecore and in my case it only resulted an item with the workflow state set in the english language, not my current context language. This might be something that you experience in your situation.

Can solr return function values (not solr score or document fields)?

We are making a solr query where we are giving a custom function (which is pretty complex) and sorting the results by value of that function. The query looks something like:
solr/select?customFunc=complexFunction(querySpecificValue1,querySpecificValue2)&sort_by=$customFunc&fq=......
Our understanding is that we can only get back fields on the document and solr score back from solr. Can someone tell us if and how we can fetch the computed value of customFunc for each document. For some reasons we cannot set solr score to be customFunc.
You should use the fl parameter to select pseudo fields, functions and so on, but this is supported only on trunk, which will be released with the 4.0 version of Solr. Have a look at the CommonQueryParameters wiki. The SOLR-2444 issue might be interesting too.
A brief example:
solr/select?q=*:*&fl=*,customFunc:complexFunction(querySpecificValue1,querySpecificValue2)
This helped me :
/solr/auction-En/select/?q=*:*_val_:"sum(x,y)"&debugQuery=true&version=2.2&start=0&rows=10&indent=on&fl=*,score
You will see the values of the function in the debug part.

Dynamically building CAML query in SharePoint 2010

I have an requirement of get the items from the list depends on the ItemID.I have list which contains 5000 items in which I retrieve only 1000 items for that I will dynamically build the CAML query using JohnHoliday CAML.NET and the query have 1000 conditions at that time I got Value does not fall within the Expected Range error. The query works fine upto 150 items but it throws error when the ItemID increases.Could you provide a suitable workaround for this issue ?
You're running into the size limit for CAML queries, which AFAIK isn't documented anywhere, but definitly exists.
If you only need to support 2010 then you can use the new <In> operator which probably with get you a bid further
In sharepoint 2010 there is a List view threshold configuration that give the administrator the ability to determine the maximum items you can retreive in a one patch
and to overcome this problem you can use
ContentIterator
check this link for more help
Why not iterate over SPList.Items and take which items you need? So there's no need to build a complex caml query. Or call SPList.GetItemByUniqueId.

Query and/or Search for SharePoint Document ID

We have the sharepoint 2010 environment with Document ID's enabled.
Given (part of) a Doc ID, we want to programmatically retrieve the document(s) matching that ID. The problem seems to be that this column is rather special, in that it might need special handling.
Using an SPSiteDataQuery, fetching the _dlc_DocId field as part of the viewfields works fine. However, including it as part of the where query never results in any documents being fetched.
Using the Search API has gotten us nowhere at all.
Has anyone pulled this off, or any suggestions on how to tackle this problem?
[Update] Turns out we were fooled by subtle errors in the XML and bad debugging misinterpretations. This stuff just works fine.
I don't normally contribute to these sorts of things because cleverer people than I always get there before me, but as this is an old one with no proper answer I think I'll add my thoughts for those who find this page.
I was struggling with this but after a little digging around and learning a bit of Caml I got this working.
I am using the SharePoint Client Object Model against SharePoint 2010 and Office365 beta.
Start off your query by looking at the all list items query:
Microsoft.SharePoint.Client.CamlQuery.CreateAllItemsQuery().ViewXml
"<View Scope=\"RecursiveAll\">\r\n <Query>\r\n </Query>\r\n</View>"
Stick a where child inside the query
Then add in
<Eq><FieldRef Name="_dlc_DocId" /><Value Type="Text">MDXC2KE55ASN-3-80</Value></Eq>
replacing MDXC2KE55ASN-3-80 with the doc ID you are looking for inside the where.
Also don't forget you might want to make use of these too:
<ViewFields><FieldRef Name="_dlc_DocId" /></ViewFields>
<RowLimit>1</RowLimit>
Then use List.GetItems() method to bring back the ListItemCollection.
Just in case nobody comes with a slick solutions from the depths of the Sharepoint infrastructure:
What would Google Do?
Slice is, Dice it and dump it in a reverse index.
Solr and Lucene offer supreme tools for this. The idea is to cut the DocId's in small pieces and add the location of the document to the bucket for that piece.
Say We have "A real nice document" with Id ABCD123. You would add it to the buckets
ABCD, BCD1, CD12, D123
When searching for a partial ID (+ other data like dates, types, ...) you (well the search engine) creates the union of the buckets + applies additonal constraints.
To make this happen you need to write a spider for the sharepoint server and a routine which makes a record of data elements to be indexed.
Put a nice REST interface in frnt of it (actually SOLR already has that), integrate it in the main sharepoint server, and nobody needs to know there is something else running behind it.
These products can also incrementally update the indexes, so they can be kept up to date.
you could use the following to get the Document ID.
SPFile file = MethodToUploadFileToServer(web, filepath);
SPListItem item = file.Item;
string DocID = item.Properties["_dlc_DocId"].ToString();

Debug a Subsonic Select Query

I've got a Subsonic query that isn't returning any values. I think the problem is in my where clause, although I'm not sure why.
What I'm really looking for is a way to debug the query to see the SQL that's actually being spit out by Subsonic. I know there was a way to do this with the Query object with Inspect(), but I'm using Select objects (or could also probably use SQLQuerys) because I need joins. Is there any inspect() type option for a Subsonic Select?
Here's the code I'm using:
Dim qry As New [Select]("Contract_NO")
qry.From(<table1>.Schema)
qry.InnerJoin(<table2>.<table2columnA>, <table1>.<table1columnA)
qry.Where(NonInfoleaseLessor.Columns.LessorCode).Like("mystring")
If I comment out the where line, I get a full list of results. It doesn't like something about it, but I've manually run the query at the database with that where clause, and it works. How can I see what the difference is?
The problem with your query is that you should be using Contains("mystring") instead of Like("mystring").
The best way to see the SQL is to use the BuildSqlStatement() method of the query.
Use [a] profiler to see what SQL is actually being executed against the database.
As Adam spotted:
.Like("mystring")
should most probably be
.Like("%mystring%")
please try using Like("%mystring%")
It might have something to do with your choice of clause, or which column name you are using. Subsonic has a couple of column name field
OBJECT.xyzColumn
OBJECT.xyzColumn.QualifiedName
OBJECT.Columns.xyz
I have had to play with these in the past to get the values I wanted.

Resources