Elasticsearch/Lucene highlight - lucene

How to highlight result query with fuzzyLikeThisFieldQuery in elasticsearch? I can pick up on fuzzyQuery but not fuzzyLikeThisFieldQuery. For example, in the code below i used fuzzyQuery:
QueryBuilder allquery = QueryBuilders.fuzzyQuery("name", "fooobar").minSimilarity(0.4f);
SearchRequestBuilder builder = ds.getElasticClient()
.prepareSearch("data")
.setQuery(allquery)
.setFrom(0)
.setSize(10)
.setTypes("entity")
.setSearchType(SearchType.DEFAULT)
.addHighlightedField("name")
.addField("name");
SearchResponse sr = builder.execute().actionGet();
the result is
If you want to have a <em>foobar</em> for oracle
But if i use fuzzyLikeThisFieldQuery, didn't highlight
QueryBuilder allquery = QueryBuilders.fuzzyLikeThisFieldQuery("name").likeText("fooobar").minSimilarity(0.4f);
the result is
If you want to have a foobar for oracle
Anyone know why?

You need to call these two functions to set the highlighter tags..
builder.setHighlighterPreTags("<pre>").setHighlighterPostTags("</pre>");

I need to highlight the keyword and use the method I've written below works fine for me:
searchRequest.setQuery(
QueryBuilders.queryString(q))
.addHighlightedField("title")
.addHighlightedField("text")
.setHighlighterPreTags("<em>")
.setHighlighterPostTags("</em>");
_searchResponse = searchRequest.execute().actionGet();
I use Gson to parse response string as a json object and cast to my entity like below:
root = new JsonParser().parse(_searchResponse.toString());
p.results.add(root.getAsJsonObject().get("hits").getAsJsonObject().get("hits"));
You will get such a response like this:
content: {
results: [
[
{
_index: "news",
_type: "news",
_id: "111",
_score: 0.6056677,
_source: {
id: "1349298458",
title: "Title text",
text: "Detail text"
},
highlight: {
text: [
" some text <em>keyword</em> some text <em>keyword</em>- some text <em>keyword</em> some text."
]
}
},...
Wish you to get how it works and try it yourself.

Related

How can I retrieve nested values in Keystone 5 for my list

I'm adding a list called 'tourlocation' to my Keystone 5 project. In my mongo database my tourlocations collection has an object called 'coordinates', with two values: 'lat' and 'long'. Example:
"coordinates" : {
"lat" : 53.343761,
"long" : -6.24953
},
In the previous version of keystone, I could define my tourlocation list coordinates object like this:
coordinates: {
lat: {
type: Number,
noedit: true
},
long: {
type: Number,
noedit: true
}
Now unfortunately, when I try to define the list this way it gives the error: The 'tourlocation.coordinates' field doesn't specify a valid type. (tourlocation.coordinates.type is undefined)'
Is there any way to represent objects in keystone 5?
#Alex Hughes I believe your error says "type" which you may need to add it like this
keystone.createList('User', {
fields: {
name: { type: Text }, // Look at the type "Text" even in the MongoDB you can choose the type but it will be better to choose it here from the beginning.
email: { type: Text },
},
});
Note that noedit: true is not supported in version 5 of KeystoneJS.
For more info look at this page https://www.keystonejs.com/blog/field-types#core-field-types

Keen-io: i can't delete special event using extraction query filter

using extraction query (which used url decoded for reading):
https://api.keen.io/3.0/projects/xxx/queries/extraction?api_key=xxxx&event_collection=dispatched-orders&filters=[{"property_name":"features.tradeId","operator":"eq","property_value":8581}]&timezone=28800
return
{
result: [
{
mobile: "13185716746",
keen : {
timestamp: "2015-02-10T07:10:07.816Z",
created_at: "2015-02-10T07:10:08.725Z",
id: "54d9aed03bc6964a7d311f9e"
},
data : {
itemId: 2130,
num: 1
},
features: {
communityId: 2000,
dispatcherId: 39,
tradeId: 8581
}
}
]
}
but if i use the same filters in my delete query url (which used url decoded for reading):
https://api.keen.io/3.0/projects/xxxxx/events/dispatched-orders?api_key=xxxxxx&filters=[{"property_name":"features.tradeId","operator":"eq","property_value":8581}]&timezone=28800
return
{
properties: {
data.num: "num",
keen.created_at: "datetime",
mobile: "string",
keen.id: "string",
features.communityId: "num",
features.dispatcherId: "num",
keen.timestamp: "datetime",
features.tradeId: "num",
data.itemId: "num"
}
}
plz help me ...
It looks like you are issuing a GET request for the delete comment. If you perform a GET on a collection you get back the schema that Keen has inferred for that collection.
You'll want to issue the above as a DELETE request. Here's the cURL command to do that:
curl -X DELETE "https://api.keen.io/3.0/projects/xxxxx/events/dispatched-orders?api_key=xxxxxx&filters=[{"property_name":"features.tradeId","operator":"eq","property_value":8581}]&timezone=28800"
Note that you'll probably need to URL encode that JSON as you mentioned in your above post!

dojo FilteringSelect avoid Accented characters

I'm using a FilteringSelect that use an FilteringSelect as store.
I want to ignore the accented characters that users can enter, and to return all the elements with or without accents. But i don't know what event i have to catch.
Here's my code :
var ccppMemory = new dojo.store.FilteringSelect({
data: centrosPoblado,
idProperty: "id"
});
sboMunicipio = new dijit.form.FilteringSelect({
id: "soMunicipioSelect",
hasDownArrow: false,
placeholder: i18n.tools.searches.ordinary.departmentTown,
store: ccppMemory,
searchAttr: "unitario",
intermediateChanges : true,
queryExpr: "*${0}*",
autoComplete: false,
highlightMatch: "all",
style:"margin-right:5px;width:170px;"
}, "soMunicipioSelect");
sboMunicipio.startup();
To explain better, centrosPoblado is an array that i populate as :
centrosPoblado.push({
id: value.attributes.CODIGO_DANE,
label: value.attributes.NOMBRE_CENTRO_POBLADO,
unitario: value.attributes.DEPTO + " / " + value.attributes.NOMBRE_CENTRO_POBLADO
});
In 'unitario' i have store strings like 'Medellín', ' Bogotá', ....
What i want is that when a user enter medellín, the filterselect ignore and returns 'Medellín' . So what i think i have to do it's to substitute medellin for something like m[eé]d[eé]ll[íi]n, but i don't know where.
Thanks
if anyone is interested, here is the answer :
http://dojo-toolkit.33424.n3.nabble.com/FilteringSelect-avoid-Accented-characters-td4004099.html
You have to overwrite the 'queryEngine' of the Memory that its linked to the FilteringSelect

Dojo DGrid RQL Search

I am working with a dgrid where I want to find a search term in my grid on two columns.
For instance, I want to see if the scientific name and commonName columns contain the string "Aca" (I want my search to be case insensitive)
My Grid definition:
var CustomGrid = declare([Grid, Pagination ]);
var gridStore = new Memory({ idProperty: 'tsn', data: null });
gridStore.queryEngine = rql.query;
grid = new CustomGrid({
store: gridStore,
columns:
[
{ field: "tsn", label: "TSN #"},
{ field: "scientificName", label: "Scientific Name"},
{ field: "commonName", label: "Common Name",},
],
autoHeight: 'true',
firstLastArrows: 'true',
pageSizeOptions: [50, 100],
}, id);
With the built in query language (I think simple query language), I was able to find the term in one column or the other, but I couldn't do a complex search that would return results for both columns.
grid.set("query", { scientificName : new RegExp(speciesKeyword, "i") });
grid.refresh()
I started reading and I think RQL can solve this problem, however, I am struggling with the syntax.
I have been looking at these pages:
http://rql-engine.eu01.aws.af.cm/
https://github.com/kriszyp/rql
And I am able to understand basic queries, however the "contains" syntax eludes me.
For instance if I had this simple data set and wanted to find the entries with scientific and common names that contain the string "Aca" I would think my contains query would look like this:
contains(scientificName,string:aca)
However, this results in no matches.
[
{
"tsn": 1,
"scientificName": "Acalypha ostryifolia",
"commonName": "Rough-pod Copperleaf",
},
{
"tsn": 2,
"scientificName": "Aegalius acadicus",
"commonName": "Northern Saw-whet Owl",
},
{
"tsn": 3,
"scientificName": "Portulaca pilosa",
"commonName": "2012-02-01",
},
{
"tsn": 4,
"scientificName": "Accipiter striatus",
"commonName": "Kiss-me-quick",
},
{
"tsn": 5,
"scientificName": "Acorus americanus",
"commonName": "American Sweetflag",
}
]
Can someone guide me in how to formulate the correct syntax? Thank you.
From what I'm briefly reading, it appears that:
contains was replaced by any and all
these are meant for array comparisons, not string comparisons
I'm not sure offhand whether RegExps can just be handed to other operations e.g. eq.
With dojo/store/Memory, you can also pass a query function which will allow you to do whatever you want, so if you wanted to compare for a match in one field or the other you could do something like this:
grid.set('query', function (item) {
var scientificRx = new RegExp(speciesKeyword, 'i');
var commonRx = new RegExp(...);
return scientificRx.test(item.scientificName) || commonRx.test(item.commonName);
});
Of course, if you want to filter only items that match both, you can do that with simple object syntax:
grid.set('query', {
scientificName: scientificRx,
commonName: commonRx
});

dijit.form.ComboBox with complex drop-down menu

I'd like to create a more interesting blog autocomplete widget; one that will return a drop-down menu that will contain: (a) title, (b) keywords, (d) date. E.g.:
|======================
| inte|
|======================
| Interesting Title
| Tags: title, bar
| Date: Jun, 12 2010
|----------------------
| Interner Guide
| Tags: guide
| Date: Aug, 12 2010
|----------------------
| ...
|======================
I. First Option
One way of achieving this is by overriding the _createOption of the _ComboBoxMenu like this:
dojo.declare("SearchBox", dijit.form.ComboBox, {
postMixInProperties: function() {
this._popupWidget = new SearchBoxMenu();
this.inherited(arguments);
}
});
dojo.declare("SearchBoxMenu", dijit.form._ComboBoxMenu, {
_createOption: function(item, labelFunc) {
var menuitem = dojo.doc.createElement("li");
menuitem.innerHTML = [
"<ul>",
"<li>", store.getValue(item, "title"), "</li>",
"<li>Tags: ", store.getValue(item, "tags"), "</li>",
"<li>Date: ", store.getValue(item, "date"), "</li>"
"</ul>"
].join("")
return menuitem;
}
});
But I'm (a) overriding a private class, then (b) it's private method, so if the method signature changes for these classes in dojo 1.6 -- I'll be in trouble. This makes this way a bit undesirable.
II. Second Option
The second way will not break if the private API signature changes, but does mix data with presentation:
var myStore = new dojo.data.ItemFileReadStore({
data: {
identifier: "title",
items: [
{title: "Interesting Title",
tags: "title, bar",
date: "Jun, 12 2010",
label: "<ul><li>Interesting Title</li>"
+ "<li>Tags: title, bar</li>"
+ "<li>Date: Jun, 12 2010</li></ul>"}
]
}
});
var box = new dijit.form.ComboBox({
store: myStore,
searchAttr: "title",
labelAttr: "label",
labelType: "html"
}, "ipt1"),
The labelAttr tells the ComboBox to look at the dataStore's items[].label and use that in the drop-down menu. The "labelType" tells the _ComboBoxMenu to include it as HTML instead of as a simple string. As I've mentioned above, one disadvantage of this method is that it mixes data with presentation.
Question: Thus, I have two options, but neither is perfect. Is there a better way? If not -- which one do you recommend?
The answer was described in the Rich Text Test on the "autoComplete" test page: http://archive.dojotoolkit.org/nightly/dojotoolkit/dijit/tests/form/_autoComplete.html#richtextest.
The only thing that makes me feel a bit better is that I've tried this solution before, and it didn't work with dojo 1.5. It does work on the nightlies and, hopefully, with all subsequent stable builds. It's a combination of option 2 and a label-view function:
var myStore = new dojo.data.ItemFileReadStore({
data: {
identifier: "title",
items: [
{title: "Interesting Title",
tags: "title, bar",
date: "Jun, 12 2010"}
]
}
});
var box = new dijit.form.ComboBox({
autoComplete: false,
selectOnClick: true,
store: myStore,
searchAttr: "title",
labelType: "html",
labelFunc: function(item, store) {
return [
"<ul>",
"<li>", store.getValue(item, "title"), "</li>",
"<li>Tags:", store.getValue(item, "tags"), "</li>",
"<li>Date:", store.getValue(item, "date"), "</li>",
"</ul>"
].join("")
}
}, "ipt1");
I don't think there is a better way.
Personally I'd go for option 1 and keep a record of all the private APIs you're using and should check for on upgrade. Better yet, provide a patch for hooking in your own popup widget and submit it, making sure the next version has the change you want to see in it :)