Ответ 1
Я столкнулся с этой проблемой при попытке импортировать данные из нескольких коллекций в mongoDB.
Предполагая, что вы не используете mongo-коннектор, я использовал следующее для импорта данных.
- Solr-6.6.0
- Solr-dataimporthandler-6.6.0
- mongo-java-driver-3.5.0
- Импортер Solr Mongo
Так как возвращенный "_id" имеет тип ObjectId, моя работа вокруг решения заключалась в том, чтобы преобразовать "_id" в String, прежде чем индексировать его в solr и при запросе в отношении "_id" , преобразовать его в тип ObjectId перед запуском запрос.
Загрузите импортер solr mongo и внесите следующие изменения.
MongoMapperTransformer.java
public class MongoMapperTransformer extends Transformer {
@Override
public Object transformRow(Map<String, Object> row, Context context) {
for (Map<String, String> map : context.getAllEntityFields()) {
String mongoFieldName = map.get(MONGO_FIELD);
String mongoId = map.get(MONGO_ID);
if (mongoFieldName == null)
continue;
String columnFieldName = map.get(DataImporter.COLUMN);
//If the field is ObjectId convert it into String
if (mongoId != null && Boolean.parseBoolean(mongoId)) {
Object srcId = row.get(columnFieldName);
row.put(columnFieldName, srcId.toString());
}
else{
row.put(columnFieldName, row.get(mongoFieldName));
}
}
return row;
}
public static final String MONGO_FIELD = "mongoField";
//To identify the _id field
public static final String MONGO_ID = "objectIdToString";
}
Далее, Замените функцию
public Iterator <Map<String, Object>> getData(String query){...}
в MongoDataSource.java со следующим:
@Override
public Iterator<Map<String, Object>> getData(String query) {
DBObject queryObject = new BasicDBObject();
/* If querying by _id, since the id is a string now,
* it has to be converted back to type ObjectId() using the
* constructor
*/
if(query.contains("_id")){
@SuppressWarnings("unchecked")
Map<String, String> queryWithId = (Map<String, String>) JSON.parse(query);
String id = queryWithId.get("_id");
queryObject = new BasicDBObject("_id", new ObjectId(id));
}
else{
queryObject = (DBObject) JSON.parse(query);
}
LOG.debug("Executing MongoQuery: " + query.toString());
long start = System.currentTimeMillis();
mongoCursor = this.mongoCollection.find(queryObject);
LOG.trace("Time taken for mongo :"
+ (System.currentTimeMillis() - start));
ResultSetIterator resultSet = new ResultSetIterator(mongoCursor);
return resultSet.getIterator();
}
После этих изменений вы можете создать банку с помощью ant.
Скопируйте банки (импортер solr mongo и mongo-java-driver) в каталог lib. Я скопировал их в ${solr-install-dir}/contrib/dataimport-handler/lib
Добавьте директивы lib в файл solr-config.xml для указанных выше банок:
<lib dir="${solr.install.dir:../../../..}/contrib/dataimporthandler/lib" regex=".*\.jar" />
Наконец, здесь приведен пример коллекций mongo и data-config.xml
User collection
{
"_id" : ObjectId("56e9c892e4b0355017b2fa0f"),
"name" : "User1",
"phone" : "123456789"
}
Address collection
{
"_id" : ObjectId("56e9c892e4b0355017b2fa0f"),
"address" : "#666, Maiden street"
}
данных config.xml
Не забудьте указать objectIdToString = "true" для поля _id, чтобы MongoMapperTransformer мог форматировать идентификатор.
<dataConfig>
<dataSource name="MyMongo"
type="MongoDataSource"
database="test"
/>
<document name="UserDetails">
<!-- if query="" then it imports everything -->
<entity name="users"
processor="MongoEntityProcessor"
query=""
collection="user"
datasource="MyMongo"
transformer="MongoMapperTransformer">
<field column="_id" name="id" mongoField="_id" objectIdToString="true" />
<field column="phone" name="phone" mongoField="phone"/>
<entity name="address"
processor="MongoEntityProcessor"
query="{_id:'${users._id}'}"
collection="address"
datasource="MyMongo"
transformer="MongoMapperTransformer">
<field column="address" name="adress" mongoField="address"/>
</entity>
</entity>
</document>
</dataConfig>
Управляемая-схема будет иметь поле id как строку. Кроме того, если у вас есть вложенные объекты в mongodb, вам придется использовать трансформаторы script, чтобы индексировать их в solr.
Надеюсь, это поможет, Удачи!