DZone
Database Zone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
  • Refcardz
  • Trend Reports
  • Webinars
  • Zones
  • |
    • Agile
    • AI
    • Big Data
    • Cloud
    • Database
    • DevOps
    • Integration
    • IoT
    • Java
    • Microservices
    • Open Source
    • Performance
    • Security
    • Web Dev
DZone > Database Zone > How to Boost Documents from within Solar using MongoDB

How to Boost Documents from within Solar using MongoDB

Kelvin Tan user avatar by
Kelvin Tan
·
Jun. 12, 12 · Database Zone · Interview
Like (0)
Save
Tweet
7.00K Views

Join the DZone community and get the full member experience.

Join For Free

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)

MongoDB Boost (C++ libraries)

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

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Autowiring in Spring
  • Debugging Deadlocks and Race Conditions
  • Ultra-Fast Microservices: When Microstream Meets Payara
  • Refactoring Java Application: Object-Oriented And Functional Approaches

Comments

Database Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • MVB Program
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends:

DZone.com is powered by 

AnswerHub logo