Azure Search and using ends with in Array - azure-cognitive-search

I am using the latest Microsoft.Azure.Search SDK with the following search parameters. I have filter ID's that are MFR-1, MFR-2, MFR-3, etc. I am trying to bring back ANY record that has Filter ID that starts with MFR.
It seems that this should be simple query, but I am not finding a way to make this work with the SDK.
var Params = new SearchParameters()
{
SearchMode = SearchMode.Any,
QueryType = QueryType.Full,
Top = 72,
Skip = 0,
IncludeTotalResultCount = true,
Filter = "FilterIDs/any(c: c eq 'MFR-57')",
OrderBy = new List<string> { "Sort", "Title"},
Facets = new List<string>() { "Filters,count:500,sort:value" }
};
Data looks like this:
{
"id": "691",
"RecordType": "product",
"FilterIDs": [
"MFR-106",
"36-250",
"36-265"
],
}
I've tried this, but it doesn't appear to work with arrays as the title would suggest.
Contains / in array in Azure Search (Preview)

Per my understanding , you are looking for a filter express that could filter all record whose FilterIDs string collection(array) contains item value started with "MFR" .
As official doc indicated :
Inside lambda expressions for string collections, the only comparison
operators that can be used are eq and ne.
So I am afraid there is no way to do fuzzy search here.
But if your filter ids are enumerable , maybe you can use the filter express as below :
FilterIDs/any(c: c eq 'MFR-1') or FilterIDs/any(c: c eq 'MFR-2') or FilterIDs/any(c: c eq 'MFR-3') or ....
I think it would be a work around here, it works for me on my side .
Hope it helps.

Related

Gatling: Map fields from Json Response to a Map Object

My response looks like this
{
"data":[
{
"id":"919274ee42fe01d40f89f51239009a2b",
"descriptor":"Long Count_copy_1938",
"alias":"longCount_Copy_1938",
"type":"Numeric"
},
{
"id":"435274ee42fe01d40f89f51239009a2b",
"descriptor":"Long Count2",
"alias":"longCount_Copy2",
"type":"Numeric"
},
{
"id":"345274ee42fe01d40f89f51239009a2b",
"descriptor":"Short Count2",
"alias":"Short count",
"type":"Numeric"
}
]
}
I would like to extract "descriptor":"id" to a Map. After mapping, the Map object should look like
"Long Count_copy_1938" -> "919274ee42fe01d40f89f51239009a2b"
"Long Count2" -> "435274ee42fe01d40f89f51239009a2b"
"Short Count2" -> "345274ee42fe01d40f89f51239009a2b"
Here is how I am achieving it, Let me know if there is a better way. Thanks!
exec(http("Get Field ids")
.get(s"${wqlDataSources}/")
.check(status.is(200),
jsonPath("$.data[*].descriptor").findAll.saveAs("descriptors"),
jsonPath("$.data[*].id").findAll.saveAs("ids")))
.exec(session => {
val descriptors = session("descriptors").as[Vector[String]]
val ids = session("ids").as[Vector[String]]
val fieldIdMap = (descriptors zip ids).toMap
session.set("fieldIdResultMap", fieldIdMap)
session.remove("descriptors").remove("ids")
})
Most JSONPath implementations support to extract multiple values in one go using the [,] union operator, e.g. $..['id','descriptor'] to matches your two properties.
(However, the availability and the result of the union is neither universal nor consistent, if you check the above path online here by switching to Goessner or Jayway you will notice the result are not the same, the Gattling tab on the test site even throws an error; I cannot tell if it would work if the site would use the latest version.)
I could not find any documentation that confirmed Gatling supports unions but I found this test on Gatling's Github repo that has a union: JsonPath.query("$.menu['file','year']", json) ... So, unioning should work, in general.
With some trial and error, I found this path that works using Gatling (even with older versions):
$.data[*]['id','descriptor']
Which returns:
[
"919274ee42fe01d40f89f51239009a2b",
"Long Count_copy_1938",
"435274ee42fe01d40f89f51239009a2b",
"Long Count2",
"345274ee42fe01d40f89f51239009a2b",
"Short Count2"
]
So, you should be able to map the key/value pairs in one go using this path!
Here is 1 more solution that worked,
exec(http("Get Field ids for the data source")
.get(s"${wqlDataSources}/" + "${datasourceId}/fields)
.check(status.is(200),
jsonPath("$.data[*].descriptor").findAll.saveAs("descriptors"),
jsonPath("$.data[*].id").findAll.saveAs("ids")))
.exec(session => {
val descriptors = session("descriptors").as[Vector[String]]
val ids = session("ids").as[Vector[String]]
val currentFieldIdMap = (descriptors zip ids).toMap
})

DotNet Core Azure Search SDK - filtering results

We are trying to implement Filter functionality into Azure (Cognitive) Search. I was hoping to find some nice SDK methods that hide all the ugly parts, but so far the only example I found looks like this (source):
SearchParameters parameters = new SearchParameters()
{
Filter = String.Format("groupIds/any(p:search.in(p, '{0}'))", string.Join(",", groups.Select(g => g.ToString()))),
Select = new[] { "application essays" }
};
I was wondering, whether I am missing some docs. Or maybe it is on the roadmap?
Check out our new Azure.Search.Documents SDK we released last month. It does have OData filter helps as you can find here:
int stars = 4;
SearchOptions options = new SearchOptions
{
// Filter to only Rating greater than or equal our preference
Filter = SearchFilter.Create($"Rating ge {stars}"),
Size = 5, // Take only 5 results
OrderBy = { "Rating desc" } // Sort by Rating from high to low
};
It'll escape string parameters correctly. The OData $filter syntax still requires raw input, but the type helpers in the formattable string should make your situation easier: you don't have to worry about escaping values yourself.

Using variables in azure search filter

I am creating a search for a website and using many filter options. I want to use filter on my many search results and for that i saw Filter property in SearchParameters for Azure Cognitive search.
What i want is to pass a variable in Filter when i try to pass those parameters in filter search.
Is there any possible way that i do not have to manually pass the Boulevard House from my data and use the variable houseName instead as i have provided options to choose and this is just plain-hardcode.
Any refernce will help as well, as i tried to read the documents but in vain.
{
Filter = String.Format("HouseName eq '{0}'", houseName)
} ;
var names = new List<Search>();
if (nameResult.Results.Count > 0)
{
foreach (SearchResult<Search> results in nameResult.Results)
{
names.Add(results.Document);
}
}
NameSearchViewModel nameSearchViewModel = new NameSearchViewModel();
nameSearchViewModel.Grants = names;
return View(namesSearchViewModel);
I'm assuming you are using the C# SDK. You could do something like this
parameters = new SearchParameters
{
Filter = String.Format("HouseName eq '{0}'", houseName)
}

How to apply angular filter to an array

I am trying to apply Angular filter to the following array after following the instructions here http://docs.angularjs.org/api/ng.filter:filter:
[{"id":"compute-1.amazonaws.com_Delivery","id":"compute-1.amazonaws.com_TaskJob","id":"UpdateFiles","id":"TaskRequest"}]
Say the filter values are:
filter = "TaskRequest";
filter = "Taskjob";
filter = "UpdateFiles";
filter = "Delivery";
How can I apply Angular filter:
I have tried:
conData = JSON.stringify(data);
results = $filter('filter')(conData, filter, false);
I have also tried :
results = $filter('filter')(conData, filter, true);
results = $filter('filter')(conData, filter);
When I examine the results of the filter nothing changes and I get back the same array.
So if the filter applied was "Delivery"
The results array would be :
[{"id":"compute-1.amazonaws.com_Delivery"}]
What am I doing wrong here?
Not sure if it is a copy/paste mistake but the array you provide in your first source extract is wrong (or at least won't do what you expect). If you look closely the key id is repeated inside the same JSON object. Try with the following array :
[
{"id":"compute-1.amazonaws.com_Delivery"},
{"id":"compute-1.amazonaws.com_TaskJob"},
{"id":"UpdateFiles"},
{"id":"TaskRequest"}
];
BTW I assembled a lighter version of your code accessible here where the filtering is working.

Using CouchDB-lucene how can I index an array of objects (not values)

Hello everyone and thanks in advance for any ideas, suggestions or answers.
First, the environment: I am using CouchDB (currently developing on 1.0.2) and couchdb-lucene 0.7. Obviously, I am using couchdb-lucene ("c-l" hereafter) to provide full-text searching within couchdb.
Second, let me provide everyone with an example couchdb document:
{
"_id": "5580c781345e4c65b0e75a220232acf5",
"_rev": "2-bf2921c3173163a18dc1797d9a0c8364",
"$type": "resource",
"$versionids": [
"5580c781345e4c65b0e75a220232acf5-0",
"5580c781345e4c65b0e75a220232acf5-1"
],
"$usagerights": [
{
"group-administrators": 31
},
{
"group-users": 3
}
],
"$currentversionid": "5580c781345e4c65b0e75a220232acf5-1",
"$tags": [
"Tag1",
"Tag2"
],
"$created": "/Date(1314973405895-0500)/",
"$creator": "administrator",
"$modified": "/Date(1314973405895-0500)/",
"$modifier": "administrator",
"$checkedoutat": "/Date(1314975155766-0500)/",
"$checkedoutto": "administrator",
"$lastcommit": "/Date(1314973405895-0500)/",
"$lastcommitter": "administrator",
"$title": "Test resource"
}
Third, let me explain what I want to do. I am trying to figure out how to index the '$usagerights' property. I am using the word index very loosely because I really do not care about being able to search it, I simply want to 'store' it so that it is returned with the search results. Anyway, the property is an array of json objects. Now, these json objects that compose the array will always have a single json property.
Based on my understanding of couchdb-lucene, I need to reduce this array to a comma separated string. I would expect something like "group-administrators:31,group-users:3" to be a final output.
Thus, my question is essentially: How can I reduce the $usagerights json array above to a comma separated string of key:value pairs within the couchdb design document as used by couchdb-lucene?
A previous question I posted regarding indexing of tagging in a similar situation, provided for reference: How-to index arrays (tags) in CouchDB using couchdb-lucene
Finally, if you need any additional details, please just post a comment and I will provide it.
Maybe I am missing something, but the only difference I see from your previous question, is that you should iterate on the objects. Then the code should be:
function(doc) {
var result = new Document(), usage, right;
for(var i in doc.$usagerights) {
usage = doc.$usagerights[i];
for(right in usage) {
result.add(right + ":" + usage[right]);
}
}
return result;
}
There's no requirement to convert to a comma-separated list of values (I'd be intrigued to know where you picked up that idea).
If you simply want the $usagerights item returned with your results, do this;
ret.add(JSON.stringify(doc.$usagerights),
{"index":"no", "store":"yes", "field":"usagerights"});
Lucene stores strings, not JSON, so you'll need to JSON.parse the string on query.

Resources