Over a million developers have joined DZone.

How to Boost Documents from within Solar using MongoDB

· Database Zone

Previously, I blogged about connecting Redis to Solr for relevance boosting via a custom FunctionQuery. Now, I'll talk about doing the same with MongoDB.

In solrconfig.xml, declare your ValueSourceParser.

<valueSourceParser name="mongo" class="org.supermind.solr.mongodb.MongoDBValueSourceParser">
  <str name="host">localhost</str>
  <str name="dbName">solr</str>
  <str name="collectionName">electronics</str>
  <str name="key">userId</str>
  <str name="idField">id</str>
</valueSourceParser>

The host, dbName and collectionName parameters are self-explanatory.

The key parameter is used to specify how to match for a MongoDB doc. The idField parameter declares the Solr field used for matching.

Here's the ValueSourceParser.

public class MongoDBValueSourceParser extends ValueSourceParser {

  private String idField;
  private String dbName;
  private String collectionName;
  private String key;
  private String host;
  private DBCollection collection;

  @Override public void init(NamedList args) {
    host = (String) args.get("host");
    idField = (String) args.get("idField");
    dbName = (String) args.get("dbName");
    collectionName = (String) args.get("collectionName");
    key = (String) args.get("key");
    try {
      Mongo mongo = new Mongo(host);
      collection = mongo.getDB(dbName).getCollection(collectionName);
    } catch (UnknownHostException e) {
      throw new IllegalArgumentException(e);
    }
  }

  @Override public ValueSource parse(FunctionQParser fp) throws ParseException {
    String value = fp.parseArg();

    final DBObject obj = collection.findOne(new BasicDBObject(key, value));
    return new MongoDBValueSource(idField, obj, value);
  }
}

Here's the interesting method in MongoDBValueSource.

  @Override public DocValues getValues(Map context, IndexReader reader) throws IOException {
    final String[] lookup = FieldCache.DEFAULT.getStrings(reader, idField);
    return new DocValues() {
      @Override public byte byteVal(int doc) {
        return (byte) intVal(doc);
      }

      @Override public short shortVal(int doc) {
        return (short) intVal(doc);
      }

      @Override public float floatVal(int doc) {
        final String id = lookup[doc];
        if (obj == null) return 0;
        Object v = obj.get(id);
        if (v == null) return 0;
        if (v instanceof Float) {
          return ((Float) v);
        } else if (v instanceof Integer) {
          return ((Integer) v);
        } else if (v instanceof String) {
          try {
            return Float.parseFloat((String) v);
          } catch (NumberFormatException e) {
            return 0;
          }
        }
        return 0;
      }

      @Override public int intVal(int doc) {
        final String id = lookup[doc];
        if (obj == null) return 0;
        Object v = obj.get(id);
        if (v == null) return 0;
        if (v instanceof Integer) {
          return (Integer) v;
        } else if (v instanceof String) {
          try {
            return Integer.parseInt((String) v);
          } catch (NumberFormatException e) {
            return 0;
          }
        }
        return 0;
      }

      @Override public long longVal(int doc) {
        return intVal(doc);
      }

      @Override public double doubleVal(int doc) {
        return floatVal(doc);
      }

      @Override public String strVal(int doc) {
        final String id = lookup[doc];
        if (obj == null) return null;
        Object v = obj.get(id);
        return v != null ? v.toString() : null;
      }

      @Override public String toString(int doc) {
        return strVal(doc);
      }
    };
  }

You can now use the FunctionQuery mongo in your search requests. For example:
http://localhost:8983/solr/select?defType=edismax&q=cat:electronics&bf=mongo(1377)

Topics:

Published at DZone with permission of Kelvin Tan. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}