Kentico Smart Search Index - any way to read it with the API? - json

We need to get a search box autocomplete working based on Kentico search indexes, but half the site is in the CMS app pages, and half is in MVC. So the autocomplete webpart works on the CMS app pages, but not the MVC ones.
An option we're exploring is to use the Twitter Typeahead js library in both sides of the site, which requires the search terms to be in a json file.
So we'd like to be able to load the search index terms via the Kentico API and then write that out to a json file.
The SearchIndexInfo object doesn't seem to have a way to get the index's terms that it writes out to the index files.
Update
For clarification: We can do the search via the API, but the searchresultitems only return with the title and content fields, and they do not contain all the search terms that are stored in the index files.
For instance, a search index for a custom page type might build the index based on the DocumentName, Description, Location, City, Company Name, DesignCategory fields. All of those will be stored in the index somewhere, so how do we read the terms that are stored in the index?
Not just the results, which would only have DocumentName(title) and Description (content).
We're basically trying to convert the search index files into a json representation, not the search results.
Of course, if the SmartSearchDialog webpart just does its predictive search on only the title and content fields, then we would just go with that, but I believe the SmartSearchDialog does an actual search does it not?
thanks

There is API for it:
// Gets the search index
SearchIndexInfo index = SearchIndexInfoProvider.GetSearchIndexInfo("NewIndex");
if (index != null)
{
// Prepares the search parameters
SearchParameters parameters = new SearchParameters()
{
SearchFor = "home",
SearchSort = "##SCORE##",
Path = "/%",
ClassNames = "",
CurrentCulture = "EN-US",
DefaultCulture = CultureHelper.EnglishCulture.IetfLanguageTag,
CombineWithDefaultCulture = false,
CheckPermissions = false,
SearchInAttachments = false,
User = (UserInfo)MembershipContext.AuthenticatedUser,
SearchIndexes = index.IndexName,
StartingPosition = 0,
DisplayResults = 100,
NumberOfProcessedResults = 100,
NumberOfResults = 0,
AttachmentWhere = String.Empty,
AttachmentOrderBy = String.Empty,
};
// Performs the search and saves the results into a DataSet
System.Data.DataSet results = SearchHelper.Search(parameters);
if (parameters.NumberOfResults > 0)
{
// The search found at least one matching result, and you can handle the results
}
}
More details here.

Roman's answer in the comments doesn't look like it would work, and in thinking about it some more we were perhaps trying to do something too complicated and weren't asking the right question maybe.
Instead of trying to replicate the search index in json for use by the twitter typeahead autocomplete, perhaps a better way to do it is to keep it simpler and just use the search results' title and content fields.
Then, in order to get additional fields into the content field of the search results ( such as project location ) we can then customize the search building code (CMSLoaderAttribute) to add the extra fields into the SearchDocument's Content field.

Related

Check to see if a JSON object value contains a phrase - django [duplicate]

This question already has an answer here:
Firebase query - Find item with child that contains string
(1 answer)
Closed 4 years ago.
I have a django project. I implimented Firebase into the project. Firebase created and returns objects in JSON format. Now, I want to have a search system through existing users and return an object that has all of the stored username values from the list and then display all of the results.
Here is a sample of a Firebase JSON object format:
OrderedDict([
('info',
{
'bio':'jogn from the office',
'company':'MySplit',
'dob':'1993-03-23',
'first_name':'jim',
'gender':'M',
'last_name':'helpert',
'phone':'+19515394856'
} ),
('location',
{
'city':'Mis Viejo',
'state':'CA',
'street':'27806 cheller',
'zip_code':98892
} ),
('status',
{
'active':'1',
'group':'dev',
'premium':'1'
} ),
('username',
'jimhelpert' )
])
I want to search and return an object with all the usernames that contain jim
I cant find how to make the query that would return all objects with username that contains the phrase...
here is the view.py:
user_id = request.session['uid']
user_profile = database.child('users').child(user_id).child('profile').get()
print(user_profile.key())
print(user_profile.val())
print(user_profile)
print(type(user_profile))
parameters = {
'user_profile':user_profile.val(),
}
return render(request, 'users/user_home.html', parameters)
Here is what the Firebase documentation has to say regarding search:
Cloud Firestore doesn't support native indexing or search for text fields
in documents.
And it goes on to say:
Additionally, downloading an entire collection to search for fields client-side isn't practical.
You could get away with this approach if your dataset is really, really small and you know for sure that it will never grow.
However, I second the suggestion from the documentation to use a dedicated search service.
To enable full text search of your Cloud Firestore data, use a third-party search service like Algolia.
Alternatively, you might consider using an SQL database which allows this kind of querying.

Razor WebPage: How to make data from the database alvailable to several pages?

My question is quite similar to this one.
I get the same data (attributes of objects, each row represents an object) from the database for two of my pages, one page to edit the data and one page to view it. To reduce redundant code and to improve maintaining I wanted to write the piece of code that loads the data only once.
My idea was to use a _PageStart.cshtml. But with that I only can store strings in the PageData array but not Objects.
So what is the best way to make the rows from the database available on several pages?
Here is how I get the data from the database:
var db = Database.Open("mydb");
String query = "select * from motors";
var rows = db.Query(query);
System.Data.DataTable motors = new System.Data.DataTable();
motors.Columns.Add("posX", typeof(int));
motors.Columns.Add("posY", typeof(int));
IEnumerator<dynamic> en = rows.GetEnumerator();
while (en.MoveNext()) {
motors.Rows.Add(en.Current.posX, en.Current.posY);
}
I would like to access the DataTable motors on different pages.
All you have to do is create a page that only has your code in it, Then on whatever page you want it displayed just use:
#RenderPage("~/yourpage.cshtml");

Umbraco Get properties of a Blog Post

I have Blog Repository and it contains blog posts list. I am accessing all Blog Posts by using this code
var contentType = ApplicationContext.Services.ContentTypeService.GetContentType("BlogPost");
var blogPostList = ApplicationContext.Services.ContentService.GetContentOfContentType(contentType.Id);
Now I am accessing custom data type properties by using
foreach (var blog in blogPostList)
{
foreach ( var property in blog.Properties)
{
}
}
Now I can access properties and get its value but for few properties I get json String and that is no use for me as I would need to create models to properly parse json string into proper json.
Is there any way to use GetPropertyValue in this situation or some other way to get properly formatted Json.
Stop right there!!! If this is for the front end DO NOT use the ContentService. This is specifically for the back end of the site, and is VERY database intensive.
For all front end code, you should be using IPublishedContent. This queries the content cache, and is MUCH faster, as there is no database access.
If you have an UmbracoHelper (which you will in Umbraco controllers), you have access to it out of the box, otherwise you need to spin up a helper. Here's an example:
var umbracoHelper = new Umbraco.Web.UmbracoHelper(Umbraco.Web.UmbracoContext.Current);
var blogPosts = umbracoHelper. TypedContentAtXPath("//BlogPost [#isDoc]");
You will then have a list of pages, and can use the standard .GetPropertyValue methods to get the values out of the fields. Note, the XPath query here isn't super efficient, you could make it a lot more specific if you wanted to.

rawQuery a ContentProvider from an external app using a ContentProviderClient

I have been struggling with an issue for a couple of days. I am sharing a Content Provider with two different apps (app A and app B). All the stuff regarding DB creation and Content Provider management is done by app A. App B just accesses it using the corresponding Authorities and a Content Provider Client.
ContentProviderClient myCPClient = this.miContext.getContentResolver().acquireContentProviderClient(this.miUri);
The problem comes up when trying to query the database in a more complex way, i.e. using some key words like GROUP BY, HAVING, etc. I need to get unique references according to one specific column (I want to use GROUP BY), and I have found out that there is no rawQuery() method for a ContentProviderClient, but a simplified query() method (compared to the one available in the class SQLiteDatabase, which allows to formulate proper MySQL commands).
I have checked this answer, but since my ContentProvider is accessed from a different app, I do not have any class like MyContentProvider.
To sum up, is there any way to make a proper query (like rawQuery()) to a ContentProvider which was generated by a different app?
I have finally got to a solution which is rather simple and sensible. I got a very good explanation about Content Providers and Content Resolvers. The latter is used to access the former, which means that they can not control what is in the provider, but get data from them. This means that you can not make a Content Provider Client to use a rawQuery() if it is not implemented (override) in the query() method of the corresponding ContentProvider.
To work around my problem, I have used a flag in my provider client and modify my content provider to read it so I can make use of GROUP BY. I just wanted to get unique references from the database according to a particular column.
Here it is the solution, which is not a very clean one, but it works quite well.
For the ContentProviderClient,
ContentProviderClient myCPClient = this.miContext.getContentResolver().acquireContentProviderClient(this.miUri);
//I declare some variables for the query
//'selection' will get all the rows whose "_id" is greater than 0, i.e. all the rows
String selection = BaseDatosParam.Tabla._ID + ">?";
String[] selectionArgs = {"0"};
//'groupBy' is not formatted in any particular way. I just need it to contain the pattern "GROUP BY"
String groupBy = "GROUP BY" + BaseDatosParam.Tabla.REF;
//the last field of the query corresponds to 'sortOrder', but I
Cursor c = myCPClient.query(Uri.parse(miUri.toString()),
projection, selection, selectionArgs, groupBy);
In the ContentProvider,
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
{
String where = selection;
String groupBy = null;
SQLiteDatabase db = this.miBDManager.getWritableDatabase();
//We just check out whether 'sortOrder' includes the pattern "GROUP BY", otherwise that field will remain null
Pattern myPat = Pattern.compile("GROUP BY");
Matcher myMat = myPat.matcher(sortOrder);
if (myMat.find())
groupBy = myMat.replaceFirst("");
Cursor c = db.query(BaseDatosParam.Tabla.NOMBRE_TABLA, projection, where, selectionArgs, groupBy, null, null);
c.setNotificationUri(this.getContext().getContentResolver(), uri);
return c;
}
Regards,

Typo3: How to read from database to produce UL for view

OK, in good old fashioned PHP MVC, I might use a model to hit the DB, send info to my PHP controller that I pass on to the View. In the View, I might take that info (say i ajax'ed my controller for the info) and create a table or ul to display the data returned.
I've had trouble finding any modern (ver 6.1 is what i'm on) tutorial to show me how to preform this action in typo3.
Can anyone just "steer" me in the right direction? Perhaps provide an example via answer, or some links to further information that may compare it down to "old fashioned MVC"?
Extension has been suggested, but I'd like to know the very base process of what I'm asking before I try writing some extension, unless the extension is the only way. Although, my table is now on the SAME DB my typo3 is on, so shouldn't there be some command to just simply call my table and get the rows? Maybe send them to a ###sub-part###?
You can use a typoscript cObj content and the select option together with the function render_obj when your table name is like the typo3 nameing convention. The select pulls the record from the table and pass it to the render_obj function. It's a function that can apply to all cObj and iterate over the entire selection. stdWrap works only on the entire cObj. When you need to work through each record you need the render_obj function. For example:
10 = CONTENT
10 {
select {
pidInList = 1
where = colpos=1
orderBy = sorting
}
table = tt_content
renderObj.stdWrap.wrap = <li>|</li>
renderObj.stdWrap.required = 1
}
10.stdWrap.wrap = <ul>|</ul>
This gives you an unorderd list from the tt_content table with pid=1 and the content from the far left column.