Sort with ignore case in an aggregation - spring-data-mongodb

I am trying to sort my result with the case insensitive option. So here is my code:
List<AggregationOperation> operations = new ArrayList<>();
Sort.Order sort = ....ignoreCase();
operations.add(new SortOperation(new Sort(sort)));
But when I execute my query using an aggregation, it doesn't work:
mongoOperations.aggregate(Aggregation.newAggregation(operations).withOptions(aggregationOptions)
I displayed the query in the debug console and the ignoreCase totally disappeared in the aggregation:
db.getCollection('persons').aggregate([
{
"$sort":{
"buyer.organization.name":-1
}
}
])
How can I put the ignore case option in my aggregation?
Thanks for your help!

The solution for this was using MongoDB Collation and add it in the mongoOperations.
I used strength = 1 which ignores cases.

This is how I solved my sorting issue
val res =
mongoTemplate.aggregate(
aggregations.withOptions(
new AggregationOptions(
false,
false,
null,
Collation.of("en").strength(Collation.ComparisonLevel.primary()))),
Path.class,
CountedAggregationFolderContentDTO.class);

Related

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.

Odata query to select empty arrays on expand?

I am clearly new to OData querying and could use some guidance. I am hoping to use $filter to filter out results and I can't seem to find a good resource for syntax. I am using Odata to select table A, expand on navigation propertyB and count all of occurrences where B is 1) an empty array, 2) has a count of 1 object or 3) has a count of greater than 1 objects. Here is an example of where I want to expand on propertyB. Any help, constructive criticism is greatly appreciated!
http://{{baseUrl}}/odata/tableA?&$top=50&$count=true&$expand=propertyB
Now, I am trying to use the filter function to filter out only the data that has propertyB as an empty array.
{
"myNumber": "00000056218",
"actionType": null,
"numberXTimes": [],
"propertyB": []
}
Here is an example where I would like to have values returned that show "propertyB" has one object:
http://{{baseUrl}}/odata/tableA?&$top=50&$expand=propertyB&$filter=contains(propertyB/myNumber, (myNumber.Length ==1))&$count=true
{
"myNumber": "00000056218",
"actionType": null,
"numberXTimes": [],
"propertyB": [
{
"myNumber": "00000056218",
"desiredId": 300387799,
}
]
}
Unfortunately, my querys aren't working. I would love your help to figure this out. Thanks in advance!
I don't have an exact solution for you, but I can provide a couple of workarounds.
First, you could use $count on your expand parameter to get the count of elements present in propertyB. This would look something like:
http://{{baseUrl}}/odata/tableA?&$top=50&$count=true&$expand=propertyB($count=true)
the response would be:
{
"myNumber": "00000056218",
"actionType": null,
"numberXTimes": [],
"propertyB#odata.count": 1,
"propertyB": [
{
"myNumber": "00000056218",
"desiredId": 300387799
}
]
}
But with this, you are just getting the count and are not actually filtering the results.
As an alternative, you could use the any() lambda function of OData to get only those entries for which propertyB is not empty, and filter out rest.
http://{{baseUrl}}/odata/tableA?&$top=50&$count=true&$expand=propertyB&$filter=propertyB/any()
I hope these workarounds work for your situation.

Azure Search and using ends with in Array

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.

Sort the columns if the flag is true-orderby angularJS

I have a table which is sorted on the name column by default.I want to enhance it to make that sorting behavior optional based on a isSortingRequired flag.How can i provide a conditional orderby clause in my template.
You can use ternary operator like
orderBy:(isSortingRequired?'CONDITION_FOR_SORT_REQUIRED':'CONDITION_FOR_SORT_NOT_REQUIRED')
Demo
orderBy:(isSortingRequired?'CONDITION_FOR_SORT_REQUIRED':'CONDITION_FOR_SORT_NOT_REQUIRED')
When '' is passed to an orderby filter it tries to sort by hashkey of the object this might create issues in the order of the records.The solution is to use a custom filter as defined below which uses the built in orderBy filter if the flag is true.
.filter('customOrder',function($filter)
{
return function(friend, prediate,isSortRequired){
if(!isSortRequired)
return friend;
else
{
var result = $filter("orderBy")(friend, prediate);
return result;
}
}
});
The solution can be seen here.This has fixed my issue.

How-to index arrays (tags) in CouchDB using couchdb-lucene

The setup:
I have a project that is using CouchDB. The documents will have a field called "tags". This "tags" field is an array of strings (e.g., "tags":["tag1","tag2","etc"]). I am using couchdb-lucene as my search provider.
The question:
What function can be used to get couchdb-lucene to index the elements of "tags"?
If you have an idea but no test environment, type it out, I'll try it and give the result here.
Well it was quite easy after I figured it out. Please realize that the $ character has no significance to the code, my fields in this case just begin with $. Posted the answer for anyone with this question in the future.
function(doc) {
var result = new Document();
for(var i in doc.$tags) {
result.add(doc.$tags[i]);
}
return result;
}
Perhaps the syntax has changed, but you can construct a view to search by any item in a document's array:
function(doc) {
for (var i=0; i<doc.page.length; i++) {
emit(doc.page[i].url, doc._id);
}
}

Resources