如何检查MongoDB数据库中所有集合的特定关键字?

问题描述 投票:2回答:2

我目前正在使用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_stringMartin,我应该从Books集合中获得相应的结果,因为Martin仅存在于那里:

 {
    "book_id": "a5g2nld”,
    "book_version": "1",
    "author": "Martin",
    "name": "Sample Book",
    “comments”: “In Progress”
  }

如果query_stringBlack,我应该从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”
  }

这似乎很棘手,我不知道该如何继续。任何帮助将不胜感激。

mongodb search mongoose mongodb-query mongoose-schema
2个回答
1
投票

这里有几个选择。它们使用基本查询和具有不同复杂程度的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);

索引和排序规则:请注意,您必须在每个集合中的相应字段上创建索引才能快速搜索。您还可以使用collat​​ion{ collation: { locale: 'en', strength: 2 } }向索引添加不区分大小写选项(用于不区分大小写的搜索)。请参阅Case Insensitive Indexes上的注释。


选项#2:

创建一个新的关键字字段,它将是您要搜索的字段中值的array。您可以将字段命名为“关键字”或“搜索字词”。

例如,带有carscar_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


0
投票

您可以这样做:

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));
                            }
                        );
                    }
                );
            }
        )
    }
);
© www.soinside.com 2019 - 2024. All rights reserved.