Search code examples
solrsolr-query-syntax

Solr: where x is between y and z


I have a Solr schema where my objects can have these two fields:

  • SerialNumberStart
  • SerialNumberEnd

For example:

"SerialNumberStart": "0000067098910",
"SerialNumberEnd": "0000067098920",

When querying, I want to be able to pass in a SerialNumberStart in my query. If that serialNumber matches on a document's serialNumberStart, I want to grab that document. However, when it doesn't match, I want to find all documents where the serialNumber I pass in is between SerialNumberStart and SerialNumberEnd. The second part of my query after the or should be something like: get the documents where someSerialStart is between documentSerialStart and documentSerialEnd.

I build up the query from JavaScript. I was trying to put the range together as follows, but it doesn't seem to be correct, yet I don't know how to fix it.

var value = req.query['matchedPattern.serialNumber'];
return 'SerialSNumberStart:' + value +  ' OR (SerialNumberStart:[* TO ' + value + '] AND SerialNumberEnd:[' + value + ' TO *])';

Thanks.


Solution

  • I updated the answer based on your clarifications. There are 4 cases you need to investigate: 1 SN exists 2 SN does not exist 2.1 Get range before SN 2.2 Get range after SN

    Intuitively, I'd definitely break it into two blocks: 1 SN exists, so serve it back to the client. Here is what it looks like:

    http://solrserver.us-west-2.compute.amazonaws.com:8983/solr/hellosolr/select?indent=on&q=id:S9V7464-APL-KIT3&wt=json
    

    The response is like:

    {
    "responseHeader":{
    "status":0,
    "QTime":0,
    "params":{
    "q":"id:S9V7464-APL-KIT3",
    "indent":"on",
    "wt":"json"}},
    "response":{"numFound":1,"start":0,"docs":[
    {
    "id":"S9V7464-APL-KIT3",
    ...
    
    1. If your SN does not exist, the response returns "numFound":1, this is when you need to run your searches. So if there is no doc, the query would look the following:

      http://solrserver.us-west-2.compute.amazonaws.com:8983/solr/hellosolr/select?indent=on&q=id:S9V7464-APL-KIT5&rows=1&sort=id%20asc&start=0&wt=json

    The response looks like:

    {
    "responseHeader":{
    "status":0,
    "QTime":0,
    "params":{
    "q":"id:S9V7464-APL-KIT5",
    "indent":"on",
    "start":"0",
    "sort":"id asc",
    "rows":"1",
    "wt":"json"}},
    "response":{"numFound":0,"start":0,"docs":[]
    }}
    

    2.1 So you need the next neighbour before the SN. There are two things I'd add to the descending range search, sorting and a limit to the number of answers. Here is what the query would like:

    http://solrserver.us-west-2.compute.amazonaws.com:8983/solr/hellosolr/select?indent=on&q=id:[*%20TO%20S9V7464-APL-KIT5]&rows=1&sort=id%20desc&start=0&wt=json
    

    The response would look like:

    {
    "responseHeader":{
    "status":0,
    "QTime":0,
    "params":{
    "q":"id:[* TO S9V7464-APL-KIT5]",
    "indent":"on",
    "start":"0",
    "sort":"id desc",
    "rows":"1",
    "wt":"json"}},
    "response":{"numFound":25,"start":0,"docs":[
    {
    "id":"S9V7464-APL-KIT3",
    "name":["Belkin Mobile Power Cord for iPod w/ Dock"],
    "manu":["Belkin"],
    "manu_id_s":"belkin",
    "cat":["electronics",
    "connector"],
    "features":["car power adapter, white"],
    "weight":[6.7],
    "price":[19.95],
    "popularity":[1],
    "inStock":[false],
    "store":["45.18014,-93.87741"],
    "manufacturedate_dt":"2005-08-01T16:30:25Z",
    "_version_":1547654166135963648}]
    }}
    

    2.2 You need an ascending range, sorted and limited by the number of returned docs. Something like:

    http://solrserver.us-west-2.compute.amazonaws.com:8983/solr/hellosolr/select?indent=on&q=id:[S9V7464-APL-KIT5%20TO%20*]&rows=1&sort=id%20asc&start=0&wt=json
    

    The response would be similar to this:

    {
    "responseHeader":{
    "status":0,
    "QTime":0,
    "params":{
    "q":"id:[S9V7464-APL-KIT5 TO *]",
    "indent":"on",
    "start":"0",
    "sort":"id asc",
    "rows":"1",
    "wt":"json"}},
    "response":{"numFound":8,"start":0,"docs":[
    {
    "id":"S9V7464-APL-KIT7",
    "name":["Belkin Mobile Power Cord for iPod w/ Dock"],
    "manu":["Belkin"],
    "manu_id_s":"belkin",
    "cat":["electronics","connector"],
    "features":["car power adapter, white"],
    "weight":[6.7],
    "price":[19.95],
    "popularity":[1],
    "inStock":[false],
    "store":["45.18014,-93.87741"],
    "manufacturedate_dt":"2005-08-01T16:30:25Z",
    "_version_":1547654166137012224}]
    }}
    

    Increasing rows returns more documents, modifying start can be used as an offset to get the Nth neighbour.