如何检查 MongoDB 数据库中所有 collections 的特定关键字?
How to check all the collections in a MongoDB database for a particular keyword?
我目前正在使用 Mongoose 查询处理 NodeJS 项目。
出现了一个新要求,我无法理解如何解决。我想获取一个查询字符串并在我的数据库的所有 collection 中搜索到 return 匹配该值的 objects。
这是我的 collection 的样子:
书籍:
{
"book_id": "ab12nld”,
"book_version": "0”,
"author": “Sam”,
“name”: “Sample Book”,
“comments”: “Done”
},
{
"book_id": "a5g2nld”,
"book_version": "1",
"author": "Martin",
"name": "Sample Book",
“comments”: “In Progress”
}
汽车:
{
"car_id": "nlp240n”,
"car_model": "3”,
"brand": “Hyundai”,
“name”: “Verna”,
“color”: “Blue”
},
{
"car_id": "cak201n”,
"car_model": "1”,
"brand": “Tata”,
“name”: “Indica”,
“color”: “Black”
}
手机:
{
"phone_id": "n0830bo”,
"brand": “OnePlus”,
“name”: “7 Pro”,
“color”: “Red”
},
{
"phone_id": "bh97b01”,
"brand": “IPhone”,
“name”: “11 Pro”,
“color”: “Black”
}
我会得到一个query_string
,在这个collection中搜索,如果有匹配的结果,我应该得到所有相关的值。
示例:
如果 query_string
是 Martin
,我应该从书籍 collection 中得到相应的结果,因为 Martin
只存在于那里:
{
"book_id": "a5g2nld”,
"book_version": "1",
"author": "Martin",
"name": "Sample Book",
“comments”: “In Progress”
}
如果 query_string
是 Black
,我应该从 Cars 和 Phones collections 得到相应的结果,因为它们的值都是 Black
:
{
"car_id": "cak201n”,
"car_model": "1”,
"brand": “Tata”,
“name”: “Indica”,
“color”: “Black”
},
{
"phone_id": "bh97b01”,
"brand": “IPhone”,
“name”: “11 Pro”,
“color”: “Black”
}
这似乎很棘手,我不知道如何进行。任何帮助将不胜感激。
这里有几个选项。这些使用基本查询和 JavaScript 具有不同的复杂程度:
选项 #1:
查询每个集合要搜索的所有字段:
var booksFound = db.books.find( { $or [ { author: <querystring>} , { name: <querystring> } ] } ).toArray()
var carsFound = db.cars.find( { $or [ { brand: <querystring> }, { name: <querystring> }, { color: <querystring> } ] } ).toArray()
var phonesFound = db.phones.find( { $or [ { brand: <querystring> }, { name: <querystring> }, { color: <querystring> } ] } ).toArray()
合并三个结果数组使用JavaScriptArrays#concat
方法得到结果:
var resultArray = booksFound.concat(carsFound).concat(phonesFound);
索引和排序规则:
请注意,您必须在每个集合中的各个字段上创建索引以加快搜索速度。您还可以使用 collation: { collation: { locale: 'en', strength: 2 } }
向索引添加 case-insensitive 选项(用于不区分大小写的搜索)。请参阅 Case Insensitive Indexes.
上的注释
选项#2:
创建一个新的 keywords 字段,它将是一个 array 的值,来自您要搜索的字段。您可以将该字段命名为 "keywords" 或 "searchwords".
例如,cars
集合的 car_id: "nlp240n"
文档,您可以将关键字字段设置为 keywords: [ "Hyundai", "Verna", "Blue"]
您需要在此数组字段上创建索引以加快查询速度。数组上的索引称为多键索引。您还可以使用排序规则向索引添加 不区分大小写 选项。 有关排序规则的更多详细信息,请参阅选项 #1。
注意:关键字字段和索引需要在三个集合上创建。
进行三个查询并将每个查询的结果作为数组获取:
var booksFound = db.books.find( { keywords: <querystring> } ).toArray();
var carsFound = db.cars.find( { keywords: <querystring> } ).toArray();
var phonesFound = db.phones.find( { keywords: <querystring> } ).toArray();
合并三个数组使用JavaScriptArrays#concat
方法得到结果:
var resultArray = booksFound.concat(carsFound).concat(phonesFound);
如何创建关键字字段数据?
每次从集合中插入、更新或删除文档( 和 如果我们正在查询的任何字段是),关键字数组需要相应地更新。
插入时将值添加到数组,更新时更改数组中的值,删除时删除数组中的值
有关详细信息,请参阅此内容:Array Update Operators。
对于你的情况,你可以这样做:
var searchValue = "Martin";
// FOR EACH COLLECTION IN MONGODB...
// HERE YOU COULD ITERAVE OVER AN ARRAY OF COLLECTIONS NAMES...
// var collections = ["Books", "Cars", "Phones"];
// collections.forEach(
db.getCollectionNames().forEach(
function(collectionName) {
// GETTING THE FIELD NAMES FOR THE COLLECTION...
// FOR COLLECTIONS WITH MANY DOCUMENTS IT MAY BE MORE INTERESTING TO GET THE FIELD NAMES ELSEWHERE INSTEAD OF MONGODB...
db.getCollection(collectionName).aggregate([
{"$project":{"arrayOfKeyValue":{"$objectToArray":"$$ROOT"}}},
{"$unwind":"$arrayOfKeyValue"},
{"$group":{"_id":null,"allFields":{"$addToSet":"$arrayOfKeyValue.k"}}},
{"$project":{"collectionName": collectionName, "fieldNames": "$allFields"}}
]).forEach(
function(collectionWithFieldNames) {
// FOR EACH FIELD NAME OF THE COLLECTION...
collectionWithFieldNames.fieldNames.forEach(
function(fieldName) {
var name = fieldName;
var value = searchValue;
var query = {};
query[name] = value;
// QUERY THE COLLECTION SEARCHING THE SEARCH VALUE ON THE FIELD IN THE COLLECTION...
db.getCollection(collectionName).find(query).forEach(
function(result) {
// PRINT THE RESULT IF EXISTS...
// HERE YOU CAN DO EVERYTHING WITH THE RESULT...
print(JSON.stringify(result));
}
);
}
);
}
)
}
);
我目前正在使用 Mongoose 查询处理 NodeJS 项目。
出现了一个新要求,我无法理解如何解决。我想获取一个查询字符串并在我的数据库的所有 collection 中搜索到 return 匹配该值的 objects。
这是我的 collection 的样子:
书籍:
{
"book_id": "ab12nld”,
"book_version": "0”,
"author": “Sam”,
“name”: “Sample Book”,
“comments”: “Done”
},
{
"book_id": "a5g2nld”,
"book_version": "1",
"author": "Martin",
"name": "Sample Book",
“comments”: “In Progress”
}
汽车:
{
"car_id": "nlp240n”,
"car_model": "3”,
"brand": “Hyundai”,
“name”: “Verna”,
“color”: “Blue”
},
{
"car_id": "cak201n”,
"car_model": "1”,
"brand": “Tata”,
“name”: “Indica”,
“color”: “Black”
}
手机:
{
"phone_id": "n0830bo”,
"brand": “OnePlus”,
“name”: “7 Pro”,
“color”: “Red”
},
{
"phone_id": "bh97b01”,
"brand": “IPhone”,
“name”: “11 Pro”,
“color”: “Black”
}
我会得到一个query_string
,在这个collection中搜索,如果有匹配的结果,我应该得到所有相关的值。
示例:
如果 query_string
是 Martin
,我应该从书籍 collection 中得到相应的结果,因为 Martin
只存在于那里:
{
"book_id": "a5g2nld”,
"book_version": "1",
"author": "Martin",
"name": "Sample Book",
“comments”: “In Progress”
}
如果 query_string
是 Black
,我应该从 Cars 和 Phones collections 得到相应的结果,因为它们的值都是 Black
:
{
"car_id": "cak201n”,
"car_model": "1”,
"brand": “Tata”,
“name”: “Indica”,
“color”: “Black”
},
{
"phone_id": "bh97b01”,
"brand": “IPhone”,
“name”: “11 Pro”,
“color”: “Black”
}
这似乎很棘手,我不知道如何进行。任何帮助将不胜感激。
这里有几个选项。这些使用基本查询和 JavaScript 具有不同的复杂程度:
选项 #1:
查询每个集合要搜索的所有字段:
var booksFound = db.books.find( { $or [ { author: <querystring>} , { name: <querystring> } ] } ).toArray()
var carsFound = db.cars.find( { $or [ { brand: <querystring> }, { name: <querystring> }, { color: <querystring> } ] } ).toArray()
var phonesFound = db.phones.find( { $or [ { brand: <querystring> }, { name: <querystring> }, { color: <querystring> } ] } ).toArray()
合并三个结果数组使用JavaScriptArrays#concat
方法得到结果:
var resultArray = booksFound.concat(carsFound).concat(phonesFound);
索引和排序规则:
请注意,您必须在每个集合中的各个字段上创建索引以加快搜索速度。您还可以使用 collation: { collation: { locale: 'en', strength: 2 } }
向索引添加 case-insensitive 选项(用于不区分大小写的搜索)。请参阅 Case Insensitive Indexes.
选项#2:
创建一个新的 keywords 字段,它将是一个 array 的值,来自您要搜索的字段。您可以将该字段命名为 "keywords" 或 "searchwords".
例如,cars
集合的 car_id: "nlp240n"
文档,您可以将关键字字段设置为 keywords: [ "Hyundai", "Verna", "Blue"]
您需要在此数组字段上创建索引以加快查询速度。数组上的索引称为多键索引。您还可以使用排序规则向索引添加 不区分大小写 选项。 有关排序规则的更多详细信息,请参阅选项 #1。
注意:关键字字段和索引需要在三个集合上创建。
进行三个查询并将每个查询的结果作为数组获取:
var booksFound = db.books.find( { keywords: <querystring> } ).toArray();
var carsFound = db.cars.find( { keywords: <querystring> } ).toArray();
var phonesFound = db.phones.find( { keywords: <querystring> } ).toArray();
合并三个数组使用JavaScriptArrays#concat
方法得到结果:
var resultArray = booksFound.concat(carsFound).concat(phonesFound);
如何创建关键字字段数据?
每次从集合中插入、更新或删除文档( 和 如果我们正在查询的任何字段是),关键字数组需要相应地更新。 插入时将值添加到数组,更新时更改数组中的值,删除时删除数组中的值
有关详细信息,请参阅此内容:Array Update Operators。
对于你的情况,你可以这样做:
var searchValue = "Martin";
// FOR EACH COLLECTION IN MONGODB...
// HERE YOU COULD ITERAVE OVER AN ARRAY OF COLLECTIONS NAMES...
// var collections = ["Books", "Cars", "Phones"];
// collections.forEach(
db.getCollectionNames().forEach(
function(collectionName) {
// GETTING THE FIELD NAMES FOR THE COLLECTION...
// FOR COLLECTIONS WITH MANY DOCUMENTS IT MAY BE MORE INTERESTING TO GET THE FIELD NAMES ELSEWHERE INSTEAD OF MONGODB...
db.getCollection(collectionName).aggregate([
{"$project":{"arrayOfKeyValue":{"$objectToArray":"$$ROOT"}}},
{"$unwind":"$arrayOfKeyValue"},
{"$group":{"_id":null,"allFields":{"$addToSet":"$arrayOfKeyValue.k"}}},
{"$project":{"collectionName": collectionName, "fieldNames": "$allFields"}}
]).forEach(
function(collectionWithFieldNames) {
// FOR EACH FIELD NAME OF THE COLLECTION...
collectionWithFieldNames.fieldNames.forEach(
function(fieldName) {
var name = fieldName;
var value = searchValue;
var query = {};
query[name] = value;
// QUERY THE COLLECTION SEARCHING THE SEARCH VALUE ON THE FIELD IN THE COLLECTION...
db.getCollection(collectionName).find(query).forEach(
function(result) {
// PRINT THE RESULT IF EXISTS...
// HERE YOU CAN DO EVERYTHING WITH THE RESULT...
print(JSON.stringify(result));
}
);
}
);
}
)
}
);