简体   繁体   English

查询:mongoDb中的字符串中匹配多少个数组元素

[英]Query for : How many elements of an array are matching within a string in mongoDb

Suppose my JSON is like following: 假设我的JSON如下所示:

{ "id":0,"keywords":"amount,debited,account,ticket,not,generated,now" }
{ "id":1,"keywords":"how,safe,gocash" }
{ "id":2,"keywords":"how,referral,program,gocash,works" }

If my array is like 如果我的数组像

array =["how","safe","gocash"];

then how do I get the count that while checking with first; 那么我如何在与首先检查时得到计数? count should be zero, with second three and with third two. 计数应为零,第二个为第三,第二个为三个。 (That means how many elements of an array are present in the string) (这意味着字符串中存在多少个数组元素)

Is it possible or what approach I should adopt? 有可能还是应该采用什么方法?

One way of solving this would require some form of modification to your schema by adding an extra field that holds the keywords in an array. 解决此问题的一种方法是,通过添加一个将keywords保存在数组中的额外字段,需要对架构进行某种形式的修改。 This field becomes quite handy when running an aggregation pipeline to return the desired count of elements of an array that match the original string. 在运行聚合管道以返回与原始字符串匹配的数组元素的所需计数时,此字段变得非常方便。

To add the additional field you would need the Bulk API operations to update the collection as follows: 要添加其他字段,您将需要Bulk API操作来更新集合,如下所示:

var bulk = db.collection.initializeOrderedBulkOp(),   
    count = 0;

db.collection.find({"keywords": { "$exists": true, "$type": 2 }}).forEach(function(doc) { 
    var keywordsArray = doc.keywords.split(',');
    bulk.find({ "_id": doc._id }).updateOne({ 
        "$set": { "keywordsArray": keywordsArray }
    });
    count++;
    if (count % 100 == 0) {
        bulk.execute();
        bulk = db.collection.initializeUnorderedBulkOp();
    }
});

if (count % 100 != 0) { bulk.execute(); }

The above creates an additional field "keywordsArray" that is a result of splitting the keywords string to an array. 上面创建了一个附加字段"keywordsArray" ,这是将keywords字符串拆分为数组的结果。

After the operation your sample collection would have the documents: 手术后,您的样品采集将具有以下文件:

/* 0 */
{
    "_id" : ObjectId("561e24e9ba53a16c763eaab4"),
    "id" : 0,
    "keywords" : "amount,debited,account,ticket,not,generated,now",
    "keywordsArray" : [ 
        "amount", 
        "debited", 
        "account", 
        "ticket", 
        "not", 
        "generated", 
        "now"
    ]
}

/* 1 */
{
    "_id" : ObjectId("561e24e9ba53a16c763eaab5"),
    "id" : 1,
    "keywords" : "how,safe,gocash",
    "keywordsArray" : [ 
        "how", 
        "safe", 
        "gocash"
    ]
}

/* 2 */
{
    "_id" : ObjectId("561e24e9ba53a16c763eaab6"),
    "id" : 2,
    "keywords" : "how,referral,program,gocash,works",
    "keywordsArray" : [ 
        "how", 
        "referral", 
        "program", 
        "gocash", 
        "works"
    ]
}

On to the next stage, the aggregation framework pipeline, run the following pipeline operation which uses the $let , $size and $setIntersection operators to work out the the desired count result: 进入下一个阶段,聚合框架管道,运行以下管道操作,该操作使用$let$size$setIntersection运算符得出所需的计数结果:

var array = ["how","safe","gocash"];
db.collection.aggregate([
    {
        "$project": {
            "id": 1, "keywords": 1,
            "count": {
                "$let": {
                   "vars": {
                      "commonToBoth": { "$setIntersection": [ "$keywordsArray", array ] }
                   },
                   "in": { "$size": "$$commonToBoth" }
                }
            }
        }
    }
])

Sample Output: 样本输出:

/* 0 */
{
    "result" : [ 
        {
            "_id" : ObjectId("561e24e9ba53a16c763eaab4"),
            "id" : 0,
            "keywords" : "amount,debited,account,ticket,not,generated,now",
            "count" : 0
        }, 
        {
            "_id" : ObjectId("561e24e9ba53a16c763eaab5"),
            "id" : 1,
            "keywords" : "how,safe,gocash",
            "count" : 3
        }, 
        {
            "_id" : ObjectId("561e24e9ba53a16c763eaab6"),
            "id" : 2,
            "keywords" : "how,referral,program,gocash,works",
            "count" : 2
        }
    ],
    "ok" : 1
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM