Abd*_*eed 9 full-text-search mongodb meteor
这是我的文档模式
"translation" : {
"en" : {
"name" : "brown fox",
"description" : "the quick brown fox jumps over a lazy dog"
},
"it" : {
"name" : "brown fox ",
"description" : " the quick brown fox jumps over a lazy dog"
},
"fr" : {
"name" : "renard brun ",
"description" : " le renard brun rapide saute par-dessus un chien paresseux"
},
"de" : {
"name" : "brown fox ",
"description" : " the quick brown fox jumps over a lazy dog"
},
"es" : {
"name" : "brown fox ",
"description" : " el rápido zorro marrón salta sobre un perro perezoso"
}
},
Run Code Online (Sandbox Code Playgroud)
现在我必须为上面的文档添加文本索引.我怎么能实现?我已经在翻译时添加了文本索引,但由于名称和描述都在语言前缀(在对象内),因此无效.我还必须分别给出名称和描述的文字权重(文本分数).即名称的文本得分为5,描述的得分为2.所以我不能给外卡文本索引即
{'$**': 'text'}
Run Code Online (Sandbox Code Playgroud)
我也尝试过,'translation.en.name': 'text'但是没有工作,而且我的语言也是动态的,因此增加了这个案例的最佳解决方案
任何帮助将不胜感激.
由于嵌入字段是动态的,因此最好的方法是修改模式,使translation字段成为嵌入文档的数组.映射当前结构的此类模式的示例如下:
"translation": [
{
"lang": "en",
"name" : "brown fox",
"description" : "the quick brown fox jumps over a lazy dog"
},
{
"lang": "it",
"name" : "brown fox ",
"description" : " the quick brown fox jumps over a lazy dog"
},
{
"lang": "fr",
"name" : "renard brun ",
"description" : " le renard brun rapide saute par-dessus un chien paresseux"
},
{
"lang": "de",
"name" : "brown fox ",
"description" : " the quick brown fox jumps over a lazy dog"
},
{
"lang": "es",
"name" : "brown fox ",
"description" : " el rápido zorro marrón salta sobre un perro perezoso"
}
]
Run Code Online (Sandbox Code Playgroud)
使用此模式,可以轻松地在name和description字段上应用文本索引:
db.collection.createIndex(
{
"translation.name": "text",
"translation.description": "text"
}
)
Run Code Online (Sandbox Code Playgroud)
至于修改架构,您需要使用api,它允许您批量更新集合,并Bulk API为您执行此操作.这些提供了更好的性能,因为您将以1000个批次的形式将操作发送到服务器,这样可以提供更好的性能,因为您不是将每个请求发送到服务器,而是每1000个请求中只发送一次.
以下演示了此方法,第一个示例使用MongoDB版本中的Bulk API> = 2.6和<3.2.它通过将所有翻译字段更改为数组来更新集合中的所有文档:
var bulk = db.collection.initializeUnorderedBulkOp(),
counter = 0;
db.collection.find({
"translation": {
"$exists": true,
"$not": { "$type": 4 }
}
}).snapshot().forEach(function (doc) {
var localization = Object.keys(doc.translation)
.map(function (key){
var obj = doc["translation"][key];
obj["lang"] = key;
return obj;
});
bulk.find({ "_id": doc._id }).updateOne({
"$set": { "translation": localization }
});
counter++;
if (counter % 1000 === 0) {
bulk.execute(); // Execute per 1000 operations
// re-initialize every 1000 update statements
bulk = db.collection.initializeUnorderedBulkOp();
}
})
// Clean up remaining operations in queue
if (counter % 1000 !== 0) { bulk.execute(); }
Run Code Online (Sandbox Code Playgroud)
下一个示例适用于新的MongoDB版本3.2,后者已弃用批量API并提供了一组较新的apis bulkWrite().
它使用与上面相同的游标,但使用相同的forEach()游标方法创建具有批量操作的数组,以将每个批量写入文档推送到数组.因为写入命令可以接受不超过1000次操作,所以您需要将操作分组以包含最多1000次操作,并在循环达到1000次迭代时重新初始化该数组:
var cursor = db.collection.find({
"translation": {
"$exists": true,
"$not": { "$type": 4 }
}
}).snapshot(),
bulkUpdateOps = [];
cursor.forEach(function(doc){
var localization = Object.keys(doc.translation)
.map(function (key){
var obj = doc["translation"][key];
obj["lang"] = key;
return obj;
});
bulkUpdateOps.push({
"updateOne": {
"filter": { "_id": doc._id },
"update": { "$set": { "translation": localization } }
}
});
if (bulkUpdateOps.length === 1000) {
db.collection.bulkWrite(bulkUpdateOps);
bulkUpdateOps = [];
}
});
if (bulkUpdateOps.length > 0) { db.collection.bulkWrite(bulkUpdateOps); }
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1433 次 |
| 最近记录: |