CAML Query to get only non duplicates - sharepoint-2013

My first goal is to get all items that has a status of 'Pending' in my sharepoint list. My code so far is like this :
using (var clientContext = new ClientContext(spSite.Trim()))
{
clientContext.Credentials = GetNetworkCredential();
var approvalLists = clientContext.Web.Lists.GetByTitle(approvalLibraryName);
CamlQuery query = new CamlQuery();
query.ViewXml = "<View>" +
"<Query>" +
"<Where>" +
"<Eq>" +
"<FieldRef Name='IsApproved'/><Value Type='Choice'>Pending</Value>" +
"</Eq>" +
"</Where>" +
"</Query>" +
"</View>";
ListItemCollection approvalListItem = approvalLists.GetItems(query);
clientContext.Load(approvalListItem);
clientContext.ExecuteQuery();
}
It is working but I then realize that a particular item can be inserted more than 1 in that list. So for example for item request_100, it can have one row for pending and another row for approved. So I need to only get those non duplicates items with status 'Pending'. Is it possible to have group by then fetch only those who have count = 1? Because I'm thinking if I could just load all items then manipulate it in using linq list. Or do you guys have another suggestion for this?

My first thought was indeed also using linq on the ItemCollection which should be working just fine.
But just a thought, if you select only the 'pending' rows, you won't get duplicates will you? Or can there be more than one item like 'request_100' with statusses 'Pending'?
Check this question which is alike to yours: https://sharepoint.stackexchange.com/questions/43262/how-to-use-groupby-in-caml-query

Related

DAX code not working with config variable used in a measure

I have a table (named Proto) in power-bi desktop as shown below (with 4 columns & around 30k rows).
I created a measure with the following DAX code. Here, ProtoVal is a table of single column containing unique values of protocol (like SSL, DNS etc). Based on the user selected protocol, i am filtering the above table to contain rows only for the selected protocol.
ProtoTotBytes =
VAR SelectedProto = SELECTEDVALUE(ProtoVal[Protocol])
VAR temp1 = FILTER(Proto, Proto[Protocol] == SelectedProto)
RETURN CALCULATE(SUM(Proto[total_bytes]), temp1)
The above DAX code works fine. Now in addition to SelectedProto, i wanted to add one more config variable numIP (TopN-IP's being a table of single column containing numerical values 5,10,15,20 etcTopN-IP's = GENERATESERIES(5, 30, 5)) where i want to take only the top 'numIP' rows from table temp1. Wrote the code below for that. This works whenever i change the value of SelectedProto but doesn't change when i change numIP ? Can anyone please let me know whey its sensitive to one config variable while it is ignoring another ?
ProtoTotBytes =
VAR numIP = SELECTEDVALUE('TopN-IP''s'[TopN-IP's])
VAR SelectedProto = SELECTEDVALUE(ProtoVal[Protocol])
VAR temp1 = FILTER(Proto, Proto[Protocol] == SelectedProto)
VAR temp2 = TOPN(numIP, temp1, [total_bytes], DESC)
RETURN CALCULATE(SUM(Proto[total_bytes]), temp2)
It does exactly what you told it to do, look at your code:
VAR temp1 = FILTER(Proto, Proto[Protocol] == SelectedProto)
VAR temp2 = TOPN(numIP, temp1, [total_bytes], DESC)
in the first line you use FILTER, this is correct, you are filtering
in the second line you are using TOPN, this is only sorting. I believe your intent was, was a filter based on your selection so also here you need to use FILTER.
VAR temp2 = FILTER(temp1, numIP = VALUE(RIGHT(Proto[networkIpAddress],1)))
In this filter I compare the last digit of the networkIp with the numIP(s) selected by the user

Why this sitecore query is not returning any items despite the fact that item with specified field value exists?

I'm trying to query one item's descendants using following query :
And not getting any items despite the fact that item with specified field value exists?
This query in query analyzer for some reason works:
select * from /sitecore/content/itema/News/descendant::*[#NewsId='235271']
Any help in correcting my code to get back item I'm searching for?
string sitecoreQuery = "descendant::*[#NewsId='" + item.Id.ToString() + "']";
Item[] newsItems = parent.Axes.SelectItems(sitecoreQuery);
Updated based on your comment:
The query looks ok, but you could also try using the shortcut for descendants: //*. I have just tested this locally and it returned me expected items.
string sitecoreQuery = "//*[#NewsId='" + item.Id.ToString() + "']";
Item[] newsItems = parent.Axes.SelectItems(sitecoreQuery);
Also double check that item.Id.ToString() is returning the Id you are expecting.
Hope that helps
You can try the following:
Item[] newsItems = Sitecore.Context.Database.SelectItems(string.Format("/sitecore/content/itema/News//*[#NewsId='{0}']", NewsId));
That should get you the filtered items

SharePoint: Efficient way to retrieve all list items

I am retrieving all items from list containing around 4000 items.
But it seems to take longer time to fetch all items which is ~15 to ~22 seconds.
Is there any best way to fetch all items from list in negligible time?
Following is the code i am using to fetch all items:
using (SPSite spSite = new SPSite(site))
{
using (SPWeb web = spSite.OpenWeb())
{
list = web.Lists["ListName"];
SPQuery query1 = new SPQuery();
string query = "<View>";
query += "<ViewFields>";
query += "<FieldRef Name='ID' />";
query += "<FieldRef Name='Title' />";
query += "</ViewFields>";
query += "<Query>";
query += "<Where>";
query += "<Eq>";
query += "<FieldRef Name='ColName'></FieldRef>";
query += "<Value Type='Boolean'>1</Value>";
query += "</Eq>";
query += "</Where>";
query += "</Query>";
query += "</View>";
query1.Query = query;
SPListItemCollection listItems = list.GetItems(query1);
}
}
Normally when it is taking this long to Retrieve items you are hitting a Boundary or limit.
First up you need to test putting a limit of your query, so you return less than 2000 items, or until you find when it starts becoming unbelievably slow.
Then you need to see if you can break your query up, or do multiple queries to get your items depending on this figure.
Cheers
Truez
Fetching many items in one shot is for sure not the best practice, or suggested way.
You have to look into alternative options, like
Column indexes: related to the version of SharePoint you're using; evaluate and test if really can give some benefits in your case
Split fetch data queries into multiple queries, by finding a group by that suits best to your data, together with the threshold. In this way you can run the queries in parallel, and likely see performance benefits
Use Search: rely on the SharePoint Search engine, quite different between SharePoint versions, but for sure this will result to be blazing fast in comparison to SPQuery. With the downsides of having to rely on search crawl schedules for getting up-to-date data

Sitecore Search Orderby

I am seeing a very strange behaviour from the Sitecore 7.1 Search when ordering by a string field. The code is something like this:
var indexableItem = new SitecoreIndexableItem(Sitecore.Context.Item);
var searchIndex = ContentSearchManager.GetIndex(indexableItem);
var context = searchIndex.CreateSearchContext();
var results = new List<Item>();
var count = 0;
var totalSearchResults = 0;
var contactColleagues = context.GetQueryable<SearchResultItem>()
.FirstOrDefault(x => x.ItemId == Sitecore.Context.Item.ID);
if (contactColleagues != null)
{
var items = contactColleagues.GetDescendants<ColleagueSearchResultItem>(context)
.Where(x => x.TemplateId == Templates.Colleague);
items = items.OrderBy(x => x.Surname);
var resultItems = items.Page(this.PageNumber, PageSize).GetResults();
}
This all works as expected and returns my dataset ordered by surname as expected. That is until a certainly individual comes along who's surname is "Or". Now Sitecore returns this persons name at the start of the list, no matter what we do.
After some testing I found the same issue happened if I decided to call someone "Andy And", this would appear at the being of the list before "Jeff Aardvark".
I'm assuming this is a bug in the way the data is being presented to the Lucene index.
Has anyone come across this, or have any thoughts about how this could be worked around?
Thanks in advance.
I think you have a problem with stop words. The default analyzer removes them when the item is crawled. You can however prevent this behaviour.
This post explains how to to turn off the stop words filter:
http://blog.horizontalintegration.com/2015/01/08/sitecore-standard-analyzer-turn-off-the-stop-words-filter/
If you look at the surname field in the index using Luke (https://code.google.com/p/luke/) is the value blank? It sounds like potentially dangerous query values are being stripped out either at the index level or as they are being loaded from the index.

SharePoint with large data

I want to discussion about SharePoint 2013 we are go on to development correspondence transaction system as product for our company on SharePoint 2013 , we expect a large data with large transaction on correspondence list we want your experience about this issue so please can you help us in this we have tow option :
development with sql database
development with SharePoint list
so please want your helpful answer with details
From my experience SharePoint is not very good to store huge amount of records (hundred thousands or even millions) in list. The reason is in the way data is stored in SharePoint database - if you check SharePoint content database you will find that all records from all lists on particular site collection are stored in one table AllListsData. The table itself is not really normalized so queries are not really fast and you get some performance loss because of the use of SharePoint as middle-ware. Moreover because all data from all lists are stored in one table if you have one huge list on site collection then it could degrade performance of whole site collection.
If you really need SharePoint I would suggest you to use separate sql database to store data and use BCS functionality to access it from SharePoint. Using this approach you can normalize data in your separate database and access data from SharePoint.
To get around it with the client Object Model you can use this code snippet, it uses item pos to leverage getting more than 5000K items. if you need VB.NET or more in-depth breakdown this is the site for you here The Snippet is from here
List list = ClientContext.Web.Lists.GetByTitle(“Assets”);
ListItemCollectionPosition itemPosition = null;
while (true) {
CamlQuery camlQuery = new CamlQuery();
camlQuery.ListItemCollectionPosition = itemPosition;
camlQuery.ViewXml = “<View>” + Constants.vbCr + Constants.vbLf + “<ViewFields>” + Constants.vbCr + Constants.vbLf + “<FieldRef Name=’Id’/><FieldRef Name=’Title’/><FieldRef Name=’Serial_No’/><FieldRef Name=’CRM_ID’/>” + Constants.vbCr + Constants.vbLf + “</ViewFields>” + Constants.vbCr + Constants.vbLf + “<RowLimit>2201</RowLimit>” + Constants.vbCr + Constants.vbLf + ” </View>”;
ListItemCollection listItems = list.GetItems(camlQuery);
clientcontext.Load(listItems);
clientcontext.ExecuteQuery();
itemPosition = listItems.ListItemCollectionPosition;
foreach (ListItem listItem in listItems) {
Console.WriteLine(“Item Title: {0} Item Key: {1} CRM ID: {2}”, listItem(“Title”), listItem(“Serial_x0020_No_x002e_”), listItem(“CRM_ID”));
}
if (itemPosition == null) {
break; // TODO: might not be correct. Was : Exit While
}
Console.WriteLine(itemPosition.PagingInfo);
Console.WriteLine();
}