Solr demote all documents with condition - solr

I want to demote all documents that have inv=0(possible values from 0 to 1000) to the end of the result set. i have got other sorting options like name desc also as part of the query.
For example below are my solr documents
Doc1 : name=apple , Inv=2
Doc2 : name=ball , Inv=1
Doc3 : name=cat , Inv=0
Doc4 : name=dog , Inv=0
Doc5 : name=fish , Inv=4
Doc6 : name=Goat , Inv=5
I want achieve below sorting ...here, i want to push all documents with inv=0 down to bottom and then apply "name asc" sorting.
Doc1
Doc2
Doc5
Doc6
Doc3
Doc4
my solr request is like
bq: "(: AND -inv:"0")^999.0" & defType: "edismax"
here 999 is the rank that i gave to demote results.
this boosting query works fine. it moves all documents with inv=0 down to the bottom.
But when i add &sort=name asc to the solr query, it prioritizes "sort" over bq..i am seeing below results with "name asc".
Doc1 : name=apple , Inv=2
Doc2 : name=ball , Inv=1
Doc3 : name=cat , Inv=0
Doc4 : name=dog , Inv=0
Doc5 : name=fish , Inv=4
Doc6 : name=Goat , Inv=5
can anyone please help me out. ?

The easy solution: You can just sort by inv first, then the other values. This requires that inv only have true (1) or false (0) values. I guess that is not the case, so:
You can sort by a function query - and you can use the function if to return different values based on whether the value is set or not:
sort=if(inv, 1, 0) desc, name desc
If Solr fails to resolve inv by itself, you can use field(inv), but it shouldn't be necessary.
Another option is to use the function min to get either 1 or 0 for the sort field, depending on whether it's in inventory or not:
sort=min(1, inv)

Related

Query for condition in array of JSON objects in PostgreSQL

Lets assume we have a PostgreSQL db with a table with rows of the following kind:
id | doc
---+-----------------
1 | JSON Object
2 | JSON Object
3 | JSON Object
...
The JSON has the following structure:
{
'header' : {
'info' : 'foo'},
'data' :
[{'a' : 1, 'b' : 123},
{'a' : 2, 'b' : 234},
{'a' : 1, 'b' : 543},
...
{'a' : 1, 'b' : 123},
{'a' : 4, 'b' : 452}]
}
with arbitrary values for 'a' and 'b' in 'data' in all rows of the table.
First question: how do I query for rows in the table where the following condition holds:
There exists a dictionary in the list/array with the key 'data', where a==i and b>j.
For example for i=1 and j=400 the condition would be fulfilled for the example above and the respective column would be returned.
Second question:
In my problem I have to deal with time series data in Json. Every measurement is represented by one Json and therefore one row in the table. I want to identify measurements where certain events occurred. For the case that the above structure is unsuitable in terms of easy querying: How could such a time series look like to be more easily queryable?
Thanks a lot!
I believe a query like this should answer your first question:
select distinct id, doc
from (
select id, doc, jsonb_array_elements(doc->'data') as elem
from docs
) as docelem
where (elem->>'a')::int = 4 and (elem->>'b')::int > 400
db<>fiddle here

MongoDb groupby count query

I have a mongoDB document having certain columns like Id, EmployeeID, SiteID, EmployeeAddress.
A employee can be present at a site more than once.
I want to have a group by query along with count which will give result set as
EmployeeID SiteID Count EmployeeAddress
basically how many times an employee is present as a site.
I am using this query but not getting the desired data.
db.pnr_dashboard.aggregate(
[
{
"$group" : {
"_id" : { "siteId" : "$siteId" , "employeeId" : "$employeeId"} ,
"count" : { "$sum":1}},
}
]
);

How to count multiple fields with group by another field in solr

I have solr document which is like below.
agentId : 100
emailDeliveredDate : 2018-02-08,
emailSentDate : 2018-02-07
agentId : 100
emailSentDate : 2018-02-06
agentId : 101
emailDeliveredDate : 2018-02-08,
emailSentDate : 2018-02-07
I need a result like below.
agentId : 100
emailDeliveredDate : 1,
emailSentDate : 2
agentId : 101
emailDeliveredDate : 1,
emailSentDate : 1
In mysql it will be :
select count(emailDeliveredDate),count(emailSentDate) group by agentId;
I need help in solr for this.
I did not get any way in Solr which can help me. So I used facet with pivot which gave me half results. Rest half calculation I did in Java.

Filter Condition in Business Object BO

I have a problem with a filter condition in BO.
Imagine that I have this database
ID | DESC
0 | None
1 | Company
2 | All
In BO I have a filter that ask where do you want to find the objects and 2 options:
"Company" or "All".
If I choose "All" then I should have all the datas with the "ID" 0,1,2 and if I choose "Company" only the data with the "ID" 1.
So I did something like this:
TABLE_NAME.ID <= (CASE WHEN #Prompt('where do you want to find the objects','A',{'Company', 'All'},mono,constrained,not_persistent,{'Company'}) = 'Company' THEN 1 ELSE 2 END)
This filter is OK when I choose "All" because I have all the "ID" smaller than 2, i.e, 0,1,2.
But It does not work when my option is company, because it also shows the data with the "ID" 0.
I should have some with "=" combined with "<="
If it's really only that simple, the following will work:
TABLE_NAME.ID =
(CASE #Prompt('where do you want to find the objects',
'A',
{'Company', 'All'},
mono,
constrained,
not_persistent,{'Company'}
)
WHEN 'Company'
THEN 1
WHEN 'All'
THEN TABLE_NAME.ID
END)

sql server 2012 : how to optimize this like % query

This query takes too much time, so I try to optimize it. Do you have any idea or suggestion ?
I tried with fulltext on a procedure and a while loop ... it gets worst ( dbo.url has more than 100 000 lines ; dbo.url where status = 'tocheck' only 1000)
select tocheck.*
from dbo.url tocheck inner join dbo.url done
on tocheck.id != done.id
and tocheck.url like done.url+'%'
and done.status in ('tocheck','todo','done')
where tocheck.status = 'tocheck'
Edit :
I call a webservice multiple times with different urls :
urls look like http://ws.com/query?p1=a&p2=b (url1).
If I already called url http://ws.com/query?p1=a (url2), i don't want to call url1 cause :
url1 like url2+'%'
Thanks for your help.
Edit2 :
I add a column suburl that contains 'query?p1=a' for each url and modify the query :
select tocheck.*
from dbo.url tocheck inner join dbo.url done
on tocheck.id != done.id
and tocheck.suburl = done.suburl --NEW
and tocheck.url like done.url+'%'
and done.status in ('tocheck','todo','done')
where tocheck.status = 'tocheck'
More than 10 times shorter ... Phew !!
I think because of joining the table to itself through ids not equal there is much overhead as this is a cartesian product only excluding self joins for same id.
I suggest trying with a subquery. Then the outer query returns only 1000 (as you mentioned) tochecks whereas the subquery additionally excludes urls starting with the same characters:
select
tocheck.*
from
dbo.url tocheck
where
tocheck.status = 'tocheck'
and
tocheck.id not in (
select
done.id
from
dbo.url done
where
tocheck.url like done.url+'%'
and
done.status in ('tocheck','todo','done')
)

Resources