「比較」または「選択」は、実際に適用される論理に実際には多少なりとも主観的です。しかし、一般的な原則として、配列と一致するインデックスの積と、ドキュメント内に存在する配列を常に検討することができます。例えば:
var sample = ["A",2,6,8,34,90];
db.getCollection('source').aggregate([
{ "$match": { "my_list": { "$in": sample } } },
{ "$addFields": {
"score": {
"$add": [
{ "$cond": {
"if": {
"$eq": [
{ "$size": { "$setIntersection": [ "$my_list", sample ] }},
{ "$size": { "$literal": sample } }
]
},
"then": 100,
"else": 0
}},
{ "$sum": {
"$map": {
"input": "$my_list",
"as": "ml",
"in": {
"$multiply": [
{ "$indexOfArray": [
{ "$reverseArray": "$my_list" },
"$$ml"
]},
{ "$indexOfArray": [
{ "$reverseArray": { "$literal": sample } },
"$$ml"
]}
]
}
}
}}
]
}
}},
{ "$sort": { "score": -1 } }
])
このような順序で文書を返す:
/* 1 */
{
"_id" : 1.0,
"my_list" : [ "A", 2, 6, 8, 34, 90],
"score" : 155.0
}
/* 2 */
{
"_id" : 2.0,
"my_list" : ["A", "F", 2, 6, 19, 8, 90, 55],
"score" : 62.0
}
/* 3 */
{
"_id" : 3.0,
"my_list" : [ 90, 34, 8, 6, 3, "A"],
"score" : 15.0
}
キー$reverseArray
を使用して適用される場合、$indexOfArray
から値となること「大きい」に一致するインデックスによって生成されます「最初から最後まで」の順序(逆順)で配列の先頭のマッチに大きな重みを与えます。
もちろん、2番目の文書には実際に一致の「ほとんど」が含まれていて、最初の文書よりも最初の一致で「より大きい」重さを配置する配列のエントリが増えることを考慮する必要があります。
"A"
は最初の位置に一致したにもかかわらず配列がより長いため、2番目の文書では最初のものよりもスコアが高くなります。しかし、"F"
がミスマッチであるため、それが後でアレイ内にある場合よりも大きな悪影響を及ぼすという効果もあります。最後の文書の"A"
にも同じことが適用されます。ここでは、配列の最後に一致が全体の重量にほとんど影響しません。
これに対処するには、サンプルの$setIntersection
と現在の配列との比較$size
など、「完全一致」の場合を考慮するロジックを追加することです。これはスコアを調整して、提供されたすべての要素にマッチしたものが、より少ない位置一致を有する文書よりも高いスコアを実際に獲得するようにする。
「スコア」を使用すると、実際の結果を返すために結果(つまり$limit
)やその他のロジックを除外することができます。しかし、最初のステップは、作業する「スコア」を計算することです。
は、だから、実際には「最も近いマッチを」何を意味するのかロジックにすべての一般的主観ですが、$reverseArray
と$indexOfArray
操作は、以前のインデックスに「より多くの重量」を置くと、一般的に鍵となる最後のではなく、一致しました。
全体として、ロジックの「計算」を探しています。集約フレームワークには利用可能な演算子がいくつかありますが、実際に適用する演算子は最終実装までです。私は、 "後者のマッチ"よりも配列の比較において、 "以前のマッチ"に "論理的にはたらく"が、しかし実際には配列が実際に同じである "最も重要な"ものを示しています。
注:同様のロジックは、上記使用される主要な演算子なしのMongoDBの以前のバージョンの$unwind
のincludeArrayIndex
オプションを使用して達成することができます。しかし、最初にアレイを分解するためには、このプロセスでは$unwind
の使用が必要です。この場合、パフォーマンスが低下するため、操作の有効性が無効になる可能性があります。
「比較する」とはどういう意味ですか?コレクション内の各ドキュメントを他のすべてのドキュメントと比較したいですか?または、代わりに、提供された配列をドキュメントに実際に格納されている配列と比較するように求めていますか?これらのアプローチは大きく異なりますので、実際にどのようなことを求めているかについては明確にする必要があります。 –
私はこの問題を修正しました。配列を提供していて、同様の配列を含むドキュメントをコレクションで検索しています。 – danspants
すべてのdocumnetsを繰り返し、コードでいくつかのロジックを使用して、mongoはこれらの種類のロジックにプロビジョニングされません。あなたはこれのためにアルゴをデザインする必要があります。 –