Sitecore:PredicateBuilder or Fast Query for retrieval - performance

I have the following structure in Sitecore 7 and I need to retrieve the descendants for those updated on 2011. How do I retrieve using fast query or PredicateBuilder?
Home
- Peek
-2009
-2010
-Article 1 (updated on 2011)
-Article 2
Home1
-Peek1
-2010
-2011
-Article 3 (updated on 2011)

With Sitecore Fast Query you can use //* to get all descendants from a node.
To get all desendants with an update date in 2011 you can use someting like this:
fast:/sitecore/content//*[#__Updated >= '20110101T000000' and #__Updated < '20120101T000000']
In Sitecore 7 you can use the XPath Builder in the Development center.
Note it is recommend to use the Sitecore Content Search API instead of a Sitecore Fast Query when you use it in code.

Related

Firestore Update document in-place vs remove and insert

I’m trying to determine which of the following has the better performance for updating a document in Firestore/NoSQL in general.
Suppose that there is a sub-collection:
friends:
- doc_id_sjfn
• last_name=Wang
• last_talked=10sec ago
• actual_user_id=wang1997
- doc_id_wokm
• last=Liu
• last_talked=12min ago
• actual_user_id=liu98
and the client attaches a listener to the sub-collection and displays the sub-collection in real-time on a list view.
Suppose that we want to change Wang’s last_talked to 15 sec ago with app engine over google cloud.
When updating the list, is the performance better when
A: delete document doc_id_sjfn and insert document with doc_id_sjfn_v2 as ID
B: update field ‘last_talked’ of document doc_id_sjfn to 15 seconds ago
Since there are warnings against updating a document in-place for more than once per second, would approach A have better performance in terms of how long it takes for the change to be reflected on the list displayed on the client device? Under what condition is this faster? (If fields are indexed vs not indexed) (if the list view contains every element under the collection vs a subset of all elements under the collection using “where”)
Thanks!
(The example was edited; there are definitely better ways of implementing this use case, but the example is here to help me express the idea of using document as a view and needing constant refresh)
The rule of once per second is for specific documents. From the looks of the data it doesn't look like data that will update more than once per... year?
I wouldn't worry about the once per second with the data set presented and just update in place. You'll introduce a headache trying to reconcile old and new documents, e.g. you have v1, how do you know there isn't a v2?

FileNet P8 ACCE Sweep job filter

I'm trying to setup a sweep job that moves a document from one class to a different class, but I only want to test right now -- not move ALL documents.
I was trying to add a filter to only pull over certain documents to test this before I pull the trigger, but it isn't working (ALL documents get listed in the results when I run this as preview).
The current filter I have is:
[DocumentTitle] like '%Z*%'
Any ideas what I need to do to change the filter to only have this run on the subset of documents I want??
Please clarify on below queries to resolve your issue:
1) Is your sweep job based on Java API / .net API? or
2) Is it based on FEM (Enterprise manager) tool
From the Filter : [DocumentTitle] like "%Z%" will filter all documents with the title %Z%, Please try to filter with ID to fetch one record, Once successful, then test with multiple records.
Thanks,
Habi
The sweep jobs typically take a condition that is similar to part after WHERE condition in search, the easiest way hence is simply to go to the search view, create your search, move to the SQL view tab, and then take whatever after WHERE condition and then add it to your sweep search filter.
Here are examples of filter conditions:
VersionStatus = 4 //All superseded documents
DateCreated < NOW() - TimeSpan(365, 'Days') //All documents that were created at least a year ago
StorageArea = OBJECT('{5E2BE09A-F4B1-49E2-A229-77FE32E5FEF1}') //All content in a specific storage area
VersionStatus = 4 AND DateCreated < NOW() - TimeSpan(365, 'Days') AND ContentSize > (1024 * 1024 * 500) //Complex logical expression
Final point in regard to your question about
I only want to test right now -- not move ALL documents.
Sweeps has Sweep Mode which defines how the sweep is going to execute, in your case you need to set it to Preview.

How do I query Sitecore items by first version created date?

It's quite easy to write an XPath or Sitecore Query/Fast query to get all items within a date range:
E.g.
/sitecore/content/*[#__created>='20130301T000000' and #__created<'20130427T000000']
However, this kind of query only looks at the latest version of an item, so it seems impossible to find the actual item's created date (not the version's created date).
I could write a bit of C# code to do the querying but that would involve first retrieving version 1 of every single item in my database before I could then do my filter on created date. This would be mind-bogglingly slow.
Is it possible to do with XPath/Query notation/Fast? If not, is there a way I can do it that will be quick?
I thought of something that might work:
Create a new field which all your items will get. Then in this field, on the creation of an item (not version), you enter the datetime in there.
When versions get deleted, that's fine, because all versions will have that field, with the exact same value.
The only thing is, you'll have to run a script once to loop through your existing items to populate the field with the correct value for each item.
You can then use your XPath query same as now.

Using date comparison in LINQ when querying SharePoint OData service

ANSWERED: Go below to find my answer to this question.
I am trying to consume SharePoint 2010 OData from an ASP.NET MVC 3 project using LINQ. I created a default project using the ASP.NET MVC 3 project template with the Razor view engine (VS 2010). I added a service reference pointing to my SharePoint 2010 site.
In my HomeController's Index method (this is just a test project), I created a variable to hold the context and set the Credentials property of the context variable to the current default credentials.
A link query like the following works fine and I can use the created variable to access any of the data:
var query = from a in context.Alerts
select a;
This query simply gets all of the announcements from a list called Alerts in the SharePoint site. This list has fields for the Title, Content, Beginning Date, and Expiration Date.
When I change the query to the following, I do not get the expected results:
var query = from a in context.Alerts
where (a.Begins < DateTime.Now)
select a;
This query ignores the time component of the date. For example, if a.Begins contains a datetime from yesterday, the query returns the AlertItem. If on the other hand, a.Begins contains a datetime with the current date (but an earlier time) the comparison returns false (and a.Begins == DateTime.Now returns true).
If I do the following, the second LINQ query works as expected:
var query = (from a in context.Alerts
select a).ToList();
var query2 = from q in query
where (q.Begins < DateTime.Now)
select q;
What am I missing?
For a Linq to SharePoint query that needs to include the time element of the DateTime you can use TimeOfDay.
var next_slots = (from s in dc.HRDates
where
s.StartTime.HasValue &&
s.StartTime.Value.Date == appt.Value.Date &&
s.StartTime.Value.TimeOfDay == appt.Value.TimeOfDay
...
I have not used SharePoint 2010's OData. However, when querying against the SharePoint 2010 object model, the anomaly you posted is a common behavior, re: you must convert the query to a list before you can query the data.
The typical pattern here is to:
var query = someSharePointQuery.ToList();
var results = query.Where(...).First(...);
Seems odd, but this is how SP 2010 seems to work.
Is DateTime.Today getting used in there somewhere? I did some prototyping with LinqPad, and the only way to duplicate your results was if I had the query using "where (a.Begins < DateTime.Today)"
Here's the quick sketch I did of what it sounds like you're describing:
void Main()
{
List<Alerts> alerts = new List<Alerts>();
alerts.Add(new Alerts(DateTime.Now.AddDays(-1)));
alerts.Add(new Alerts(DateTime.Now));
var query = from a in alerts
where (a.Begins < DateTime.Now)
select a;
foreach (var element in query)
{
Console.WriteLine(element.Begins);
}
}
public class Alerts
{
public DateTime Begins {get; set;}
public Alerts(DateTime begins)
{
Begins = begins;
}
}
As I mentioned, the only way to duplicate your described results was if I changed DateTime.Now to DateTime.Today in the where clause. I would look through your code for accidental usages of the wrong DateTime method.
As an aside, I HIGHLY recommend using LinqPad for prototyping your Linq queries... It can save you time by allowing you to quickly iterate over your code and figure out what your trouble spots are. Also, it's very much worth the $50 for intellisense and other premium features.
After piecing together information from a lot of different sources -- none of which dealt with the exact circumstances of the problem that I am having, I've come to the following conclusion:
When querying SharePoint data using the SharePoint Object Model and Collaborative Application Markup Language (CAML), SharePoint by default does not use the time component of DateTime elements when doing comparisons. To tell SharePoint to use the time component, you must include the IncludeTimeValue = 'TRUE' property on the value type as shown here:
<Where>
<Eq>
<FieldRef Name='Begins' />
<Value Type='DateTime' IncludeTimeValue='TRUE'>
2008-03-24T12:00:00Z
</Value>
</Eq>
</Where>
I found several blog posts that referenced a bug in LINQ to SharePoint that caused the generated CAML to be output as:
<Where>
<Eq>
<FieldRef Name='dateTimeField' IncludeTimeValue='TRUE' />
<Value Type='DateTime'>
2008-03-24T12:00:00Z
</Value>
</Eq>
</Where>
Notice that the IncludeTimeValue = 'TRUE' is on the FieldRef element instead of the Value element. Since this is not the right place for that property, it causes all LINQ to SharePoint queries that perform datetime comparisons to only compare on the date component.
Since I am seeing that exact same behavior when using LINQ and WCF Data Services to connect to SharePoint, I can only assume that under the covers LINQ/WCF Data Services is producing the same invalid CAML.
The solution (assuming I still want to use LINQ/WCF Data Services) is to perform two queries (as stated in the original question). The first LINQ query pulls the list data from SharePoint and stores it in a List. The second LINQ query handles the date comparisons to only pull the data I want.
Since in my particular circumstance, I may have many entries in the SharePoint list covering a large time span but will only be interested in entries on a particular day or couple of days, I wanted to find a way not to bring back the entire list in the first query.
What I settled on was doing a <= and >= comparison to get close, and then further limiting that in my second query. So my two queries now become:
DateTime RightNow = DateTime.Now;
var query = (from a in context.Alerts
where (a.Begins <= RightNow) && (a.Expires >= RightNow)
select a).ToList();
var query2 = from q in query
where q.Begins < RightNow) && (a.Expires > RightNow)
select q;
The first LINQ statement will return all the items that I am ultimately interested in; along with a few that I'm not (because it's comparing just the date component of the datetime). The second LINQ statement will further pare that down to just those that I'm interested in.
I can confirm the bug with SharePoint 2010 LINQ to SharePoint not creating the correct CAML (adding IncludeTimeValue='True' to the FieldRef instead of the Value) is fixed by the October 2013 Cumulative Update to SharePoint Foundation 2010. The hotfix can be downloaded from http://technet.microsoft.com/en-us/sharepoint/ff800847.aspx.
The same bug exists also in SharePoint 2013 which I was informed by Microsoft support should be fixed in the December 2013 Cumulative Update to SharePoint Foundation 2013, but I cannot confirm this. I was informed that the fix is also deployed to Office 365, but I cannot confirm this.

How to filter a query result?

Currently I can not quickly filter the result of a work-item query - running a query will give us a result table and within this table, there's no mean to filter the table rows to display just the ones containing some certain text.
Do you know how to filter that or have any addons/tools suggestion for that?
Thank you.
Nam.
You could use
Telerik's free Work Item Manager . It lets you search the text of work items as well as other useful filtering and grouping tools. Very useful.
We use Excel integration pretty heavily in our shop. The familiar sort and filter controls work well.
Not sure if this is what you are looking for:
You can "Edit Query" from the toolbox and save it as a new query.
After a while (long :) ), I luckily notice that there's a filter box if we browse the work items in the pending changes pane (open in VS 2010: View - Other Windows - Pending Changes). It's so nice that now I can quickly get the exact items I'm looking for.
Today, I found an addon that may fit my need: Search Work Items for TFS 2010
It is a search box, not exactly the filter for the current query.
(similar problem with this question)
I re-post the answer here:
After a long time, today I found the solution for this: use the MS VS 2010 Team Web Access to open your queries using a web browser!
Advantage when doing this:
No delay when clicking an item
Utilize all browser feature like searching, bookmark, ... to work with the queries
Enjoy!

Resources