Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MongoDB:数组项的有序匹配_Mongodb - Fatal编程技术网

MongoDB:数组项的有序匹配

MongoDB:数组项的有序匹配,mongodb,Mongodb,我有一份如下所示的文件: "tokens": [ { "index": 1, "word": "I", "pos": "NNP", }, { "index": 2, "word": "played", "pos": "VBZ", }, { "index": 3, "word": "football", "pos": "IN", } ] 我的问题是: db.test.find({ $and:

我有一份如下所示的文件:

"tokens":
[
  {
    "index": 1,
    "word": "I",
    "pos": "NNP",
  },
  {
    "index": 2,
    "word": "played",
    "pos": "VBZ",
  },
  {
    "index": 3,
    "word": "football",
    "pos": "IN",
  }
]
我的问题是:

db.test.find({
    $and: [
        {
            'tokens.word': 'I'
        },
        {
            tokens: {
                $elemMatch: {
                    word: /f.*/,
                    pos: 'IN'
                }
            }
        }
    ]
})
我的查询的输出是上面的文档。但结果应该是不匹配的,在这种情况下,因为我正在寻找

单词:“I”后跟[word:/f.*/和pos:'IN']

它与文档中的
令牌
数组不匹配,因为令牌
I
后跟
played
,然后是
football
。但是,在查询中,随着搜索的开始,过滤器的顺序是不同的

字:“我”

f*


[本例中为足球]。

$运算符是纯逻辑运算符,其中过滤条件的顺序不起任何作用

因此,从结果集的角度来看,以下查询是完全等效的:

$and: [
    { "a": 1 },
    { "b": 2 }
]

$and: [
    { "b": 2 },
    { "a": 1 }
]
各国:

$and对两个或多个阵列执行逻辑and操作 表达式(例如,等)并选择 满足数组中所有表达式的文档。美元和 操作员使用短路评估。如果第一个表达式(例如。 )计算结果为false,MongoDB将不计算 其余的表达

在您的示例中,
“index1”
条目匹配第一个过滤器
“tokens.word”:“I”
“index3”
文档匹配第二个
$elemMatch
过滤器。因此,文件必须被退回

更新:

这里有一个想法——实际上更像是一个起点——让你更接近你想要的东西:

db.collection.aggregate({
    $addFields: { // create a temporary field 
        "differenceBetweenMatchPositions": { // called "differenceBetweenMatchPositions"
            $subtract: [ // which holds the difference between
                { $indexOfArray: [ "$tokens.word", "I" ] }, // the index of first element matching first condition and
                { $min: { // the lowest index of
                    $filter: { // a filtered array
                        input: { $range: [ 0, { $size: "$tokens" } ] }, // that holds the indices [ 0, 1, 2, ..., n ] where n is the number of items in the "tokens" array - 1
                        as: "this", // which we want to access using "$$this"
                        cond: {
                            $let: {
                                vars: { "elem": { $arrayElemAt: [ "$tokens", "$$this" ] } }, // get the n-th element in our "tokens" array
                                in: {
                                    $and: [
                                        { $eq: [ "$$elem.pos", "IN" ] }, // "pos" field must be "IN"
                                        { $eq: [ { $substrBytes: [ "$$elem.word", 0, 1 ] }, "f" ] } // 1st character of the "word" must be "f"
                                    ] 
                                }
                            }
                        }
                    }
                }
            }]
        }
    }
}, {
    $match: {
        "differenceBetweenMatchPositions": { $lt: 0 } // we only want documents where the first condition is matched by an item in our array before the second one gets matched, too.
    }
})

非常感谢您的回复。我怎样才能解决这个问题?你有什么建议吗?你的过滤器应该做什么?如果我的过滤器是word:“I”&[word:/p.*/&pos:“VBZ”],那么输出应该是我玩的足球,在json文件中玩的足球有一个pos:“VBZ”,但当我输入查询搜索词:“I”&[word:/f.*/&pos:“in”]时,我不需要任何输出[我踢足球时足球有一个位置:在这种情况下,我不需要它在输出中,因为顺序不同且不完全匹配。我感谢您的帮助。根据您的查询,如果我想添加更多的条件,如a B C,其中a在a之后,B在C之后,请您解释一下如何轻松更改此查询取第一个元素并将其与数组中的每个元素进行比较,但是如果我想添加更多条件?