我目前正在使用Mongoose查询进行NodeJS项目。
提出了一个新要求,我无法理解该如何解决。我想获取一个查询字符串,并在数据库的所有集合中进行搜索,以返回与此值匹配的对象。
这是我的收藏集的外观:
书籍:
{
"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
,它将在此集合中进行搜索,如果有匹配的结果,则应获取所有相关值。
示例:
如果query_string
是Martin
,我应该从Books集合中获得相应的结果,因为Martin
仅存在于那里:
{
"book_id": "a5g2nld”,
"book_version": "1",
"author": "Martin",
"name": "Sample Book",
“comments”: “In Progress”
}
如果query_string
为Black
,我应该从Cars和Phones集合中获取相应的结果,因为这两个集合的值均为Black
:
{
"car_id": "cak201n”,
"car_model": "1”,
"brand": “Tata”,
“name”: “Indica”,
“color”: “Black”
},
{
"phone_id": "bh97b01”,
"brand": “IPhone”,
“name”: “11 Pro”,
“color”: “Black”
}
这似乎很棘手,我不知道该如何继续。任何帮助将不胜感激。
这里有几个选择。它们使用基本查询和具有不同复杂程度的JavaScript:
OPTION#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.cars.find( { $or [ { brand: <querystring> }, { name: <querystring> }, { color: <querystring> } ] } ).toArray()
[合并三个结果数组使用JavaScript Arrays#concat
方法获得结果:
var resultArray = booksFound.concat(carsFound).concat(phonesFound);
索引和排序规则:请注意,您必须在每个集合中的相应字段上创建索引才能快速搜索。您还可以使用collation:{ collation: { locale: 'en', strength: 2 } }
向索引添加不区分大小写选项(用于不区分大小写的搜索)。请参阅Case Insensitive Indexes上的注释。
创建一个新的关键字字段,它将是您要搜索的字段中值的array。您可以将字段命名为“关键字”或“搜索字词”。
例如,带有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();
[合并三个数组使用JavaScript Arrays#concat
方法获得结果:
var resultArray = booksFound.concat(carsFound).concat(phonesFound);
如何创建关键字字段数据?
每次从集合中插入,更新或删除文档(如果要查询的字段是和),则必须相应更新关键字数组。在插入时,将值添加到数组中,在更新时,更改数组中的值,在删除时,删除数组中的值
请参阅此以获取更多信息:Array Update Operators。
您可以这样做:
var searchValue = "Martin";
// FOR EACH COLLECTION IN MONGODB...
// HERE YOU COULD ITERATE OVER AN ARRAY OF COLLECTIONS NAMES...
db.getCollectionNames().forEach(
function(collectionName){
// GETTING THE FIELD NAMES FOR THE COLLECTION...
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));
}
);
}
);
}
)
}
);