Spring Data MongoDB - Criteria API OrOperator is not working properly - spring-data-mongodb

I'm facing Spring Data MongoDB Criteria API orOperator problem.
Here's query result for irregular verbs: (Terminal output)
> db.verb.find({'v2':'wrote'});
{ "_id" : ObjectId("5161a8adba8c6390849da453"), "v1" : "write", "v2" : "wrote", "v3" : "written" }
And I query verbs by their v1 or v2 values using Spring Data MongoDB Criteria API:
Criteria criteriaV1 = Criteria.where("v1").is(verb);
Criteria criteriaV2 = Criteria.where("v2").is(verb);
Query query = new Query(criteriaV1.orOperator(criteriaV2));
List<Verb> verbList = mongoTemplate.find(query, Verb.class)
But unfortunately verbList doesn't have any item.

As far as I remember in order to use orOperator you should do:
Query query = new Query(new Criteria().orOperator(criteriaV1,criteriaV2));

We need explicitly specify a new criteria with OR condition - try with below example
Criteria criteria = Criteria.where("field1").is(val1).
.andOperator(new Criteria().orOperator(Criteria.where("field2").is(filterVal),
Criteria.where("field3").is(filterVal)));

Related

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.

App engine Datastore : How make a query / filter that return entity count with specific array size?

I have an Entity with different properties, one of the propery is Array of Objects , I'm working with Java using Objectify
now I want to make a query with filter to return count of all entities only with specific array size , E.g messages size=2
Example:
Kind: Request
and
propery :
name messeges
{
"values": [
{
"K1": "V1",
"K2": "V2"
},
{
"K3": "V3",
"K4": "V4"
},
{
"K5": "V5",
"K6": "V6"
}
]
}
Something like :
int count = ofy().load().type(Request.class).filter("?? return count , to query with messages size is 2..").count()
Any suggestions plesae?
There is no way to make such query with the datastore.
But you could add a property to your entity, let's call it values_count, to reflect the values array size and make an equality query on that property instead (e.g. values_count=2)
I'd make it a computed property, automatically updated whenever the entity is updated, see Is it possible to have a computed property on Google App Engine using Java?

Ordering the solr search results based on the indexed fields

I have to order the search results from solr based on some fields which are already indexed.
My current api request is like this without sorting.
http://127.0.0.1:8000/api/v1/search/facets/?page=1&gender=Male&age__gte=19
And it gives the search results based on the indexed order. But I have to reorder this results based on the filed 'last_login' which is already indexed DateTimeField.
Here is my viewset
class ProfileSearchView(FacetMixin, HaystackViewSet):
index_models = [Profile]
serializer_class = ProfileSearchSerializer
pagination_class = PageNumberPagination
facet_serializer_class = ProfileFacetSerializer
filter_backends = [HaystackFilter]
facet_filter_backends = [HaystackFilter, HaystackFacetFilter]
def get_queryset(self, index_models=None):
if not index_models:
index_models = []
queryset = super(ProfileSearchView, self).get_queryset(index_models)
queryset = queryset.order_by('-created_at')
return queryset`
Here I have changed the default search order by 'created_at' value. But for the next request I have order based on the 'last_login' value. I have added a new parameter in my request like this
http://127.0.0.1:8000/api/v1/search/facets/?page=1&gender=Male&age__gte=19&sort='last_login'
but it gives me an error
SolrError: Solr responded with an error (HTTP 400): [Reason: undefined field sort]
How can I achieve this ordering possible? Please help me with a solution.
The URL you provided http://127.0.0.1:8000/api/v1/search/facets/ is not direct SOLR URL. It must be your middle-ware. Since you have tried the query directly against Solr and it works, the problem must be somewhere in middle-ware layer.
Try to print or monitor or check logs to see what URL the midde-ware actually generates and compare it to the valid URL you know works.

Solrnet equivalent for frange in a facet query for Distance

I have implemented Spatial Search and need to generate facets for ranges or 'buckets' of distance in Solr: the following link helped me here - http://wiki.apache.org/solr/SpatialSearch#How_to_facet_by_distance
I found the solution to the following question
Faceting on distance in solr- how to generate links that search withing a given range of distance helpful.
I am using Solrnet to generate Solr queries from my .NET based site. I cant find a link that would help me to generate a frange part (italicized) of the query as below. Please help in pointing me to the code to generate this using solrnet.
&q=:&sfield=store&pt=45.15,-93.85**&facet.query={!frange l=0 u=5}geodist()&facet.query={!frange l=5.001 u=3000}geodist()**.
I am assuming that you are already using ExtraParams to set the sField & pt parameters. You should be able to add the facet.query parameters to this as well.
var results = solr.Query(SolrQuery.All, new QueryOptions
{
ExtraParams = new Dictionary<string, string> {
{ "sfield", "store" } ,
{ "pt", "45.15,-93.85" }
{ "facet.query", "{!frange l=0 u=5}geodist()" } ,
{ "facet.query", "{!frange l=5.001 u=3000}geodist()" } ,
}
});
return results;
Additionally, you might be able to use SolrFacetQuery combined with LocalParams to build the facet queries. Check the following links for some examples:
https://code.google.com/p/solrnet/wiki/Facets
How to add Spatial Solr to a Solrnet query
Update:
As stated in the comments, the use of the ExtraParams does not work because it is a dictionary object and as a result does not allow for multiple facet.query parameters. However, I was able to use the Facet Queries as described in the SolrNet Facet Wiki page linked above to create the following:
var facet1 = new SolrFacetQuery(new SolrQuery("{!frange l=0 u=5}geodist()}"));
var facet2 = new SolrFacetQuery(new SolrQuery("{!frange l=5.001 u=3000}geodist()}"));
var results = solr.Query(SolrQuery.All, new QueryOptions
{
ExtraParams = new Dictionary<string, string>
{
{"sfield", "store"},
{"pt", "45.15,-93.85"}
},
Facet = new FacetParameters
{
Queries = new[]
{
facet1, facet2
}
}
});
return results;

How to perform an 'OR' query with S4S connector?

I'm trying figure out how to query Salesforce with multiple filters where either filter can be true (similar to a traditional WHERE x='' OR y='' SQL statement).
The following appears works, but produces an 'AND' query where both filters must be true:
var dataSource = new GenericSalesforceEntityDataSource("Download__c", GetSalesforceSession);
dataSource.AddDataSourceFilter("Contact__c", new Operator(ComparisonOperator.Equals), profile.ContactId);
dataSource.AddDataSourceFilter("Lead__c", new Operator(ComparisonOperator.Equals), profile.LeadId);
var downloads = dataSource.GetQueryResultsAsEntities();
I would like to avoid hard-coding SOQL queries into my .NET application, if possible. Does the S4S API support these sorts of queries, or should I be using SOQL for this?
The Sitecore for Salesforce Connector (S4S) has composite filters that allow you to programmatically create a DataSource that is converted into a SOQL query with OR operators in the where clause.
var dataSource = new GenericSalesforceEntityDataSource("Download__c", GetSalesforceSession);
var orFilter = new LogicalDisjunctionFilter();
orFilter.AddDataSourceFilter("Contact__c", ComparisonOperator.Equals, profile.ContactId);
orFilter.AddDataSourceFilter(ApexLog.Fields.Location, ComparisonOperator.Equals, "SystemLog");
// The two filters above will be combined with a logical OR
dataSource.AddDataSourceFilter(orFilter);
var downloads = dataSource.GetQueryResultsAsEntities();
You can use combinations of the LogicalDisjunctionFilter with the LogicalConjunctionFilter to build up AND and OR logic as required.
Alternatively, you could directly add the SOQL where clause to the datasource.
var dataSource = new GenericSalesforceEntityDataSource("Download__c", GetSalesforceSession);
dataSource.SoqlFilter = string.Format("Contact__c = '{0}' OR Location = 'SystemLog'", profile.ContactId);
var downloads = dataSource.GetQueryResultsAsEntities();
Or, as Matt suggests, you could build up your own SOQL string and run that directly.
var dataSource = new GenericSalesforceEntityDataSource("Download__c", GetSalesforceSession);
var queryResult = dataSource.RunSoqlQuery(new SoqlQuery(string.Format("Select Id from Download__c where Contact__c = '{0}' OR Location = 'SystemLog'", profile.ContactId)));
var downloads = dataSource.EntitysFromQueryResult<GenericSalesforceEntity>(queryResult);
SOQL would make this much easier so that should be the route you choose if available to you, especially since it offers the easiest way to perform logical operations with your filters.

Resources