@@ -7,7 +7,7 @@ $fill (aggregation)
7
7
.. contents:: On this page
8
8
:local:
9
9
:backlinks: none
10
- :depth: 1
10
+ :depth: 2
11
11
:class: singlecol
12
12
13
13
.. |linear-interpolation| replace:: :wikipedia:`linear interpolation <Linear_interpolation>`
@@ -252,8 +252,8 @@ For a complete example using the ``linear`` fill method, see
252
252
For a complete example using the ``locf`` fill method, see
253
253
:ref:`fill-example-locf`.
254
254
255
- Comparison of :pipeline:` $fill` and Aggregation Operators
256
- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
255
+ Comparison of `` $fill` ` and Aggregation Operators
256
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
257
257
258
258
To fill ``null`` and missing field values within a document you can use:
259
259
@@ -748,3 +748,133 @@ Example output:
748
748
score: 68
749
749
}
750
750
]
751
+
752
+ Indicate if a Field was Populated Using ``$fill``
753
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
754
+
755
+ When you populate missing values, the output does not indicate if a
756
+ value was populated with the ``$fill`` operator or if the value existed
757
+ in the document originally. To distinguish between filled and
758
+ preexisting values, you can use a :pipeline:`$set` stage before
759
+ ``$fill`` and set a new field based on whether the value exists.
760
+
761
+ For example, create a ``restaurantReviews`` collection that contains
762
+ review scores for a restaurant over time:
763
+
764
+ .. code-block:: javascript
765
+
766
+ db.restaurantReviews.insertMany( [
767
+ {
768
+ date: ISODate("2021-03-08"),
769
+ score: 90
770
+ },
771
+ {
772
+ date: ISODate("2021-03-09"),
773
+ score: 92
774
+ },
775
+ {
776
+ date: ISODate("2021-03-10")
777
+ },
778
+ {
779
+ date: ISODate("2021-03-11")
780
+ },
781
+ {
782
+ date: ISODate("2021-03-12"),
783
+ score: 85
784
+ },
785
+ {
786
+ date: ISODate("2021-03-13")
787
+ }
788
+ ] )
789
+
790
+ The ``score`` field is missing for some of the documents in the
791
+ collection. You can populate missing ``score`` values with the ``$fill``
792
+ operator.
793
+
794
+ Create a pipeline to perform the following actions:
795
+
796
+ - Add a new field to each document (using :pipeline:`$set`) indicating
797
+ if the document's ``score`` field exists prior to the ``$fill``
798
+ operator populating values. This new field is called ``valueExisted``.
799
+
800
+ - Populate missing ``score`` values with the last observed ``score`` in
801
+ the sequence. The fill method ``locf`` stands for "last observation
802
+ carried forward".
803
+
804
+ The pipeline looks like this:
805
+
806
+ .. code-block:: javascript
807
+
808
+ db.restaurantReviews.aggregate( [
809
+ {
810
+ $set: {
811
+ "valueExisted": {
812
+ "$ifNull": [
813
+ { "$toBool": { "$toString": "$score" } },
814
+ false
815
+ ]
816
+ }
817
+ }
818
+ },
819
+ {
820
+ $fill: {
821
+ sortBy: { date: 1 },
822
+ output:
823
+ {
824
+ "score": { method: "locf" }
825
+ }
826
+ }
827
+ }
828
+ ] )
829
+
830
+ .. note:: Handling Values of Zero
831
+
832
+ In the :expression:`$ifNull` expression, the ``score`` values are
833
+ converted to strings, then to booleans. The :expression:`$toBool`
834
+ expression always converts strings to ``true``. If the ``score``
835
+ values are not converted to strings, ``score`` values of ``0`` will
836
+ have ``valueExisted`` set to ``false``.
837
+
838
+ Output:
839
+
840
+ .. code-block:: javascript
841
+ :copyable: false
842
+
843
+ [
844
+ {
845
+ _id: ObjectId("63595116b1fac2ee2e957f15"),
846
+ date: ISODate("2021-03-08T00:00:00.000Z"),
847
+ score: 90,
848
+ valueExisted: true
849
+ },
850
+ {
851
+ _id: ObjectId("63595116b1fac2ee2e957f16"),
852
+ date: ISODate("2021-03-09T00:00:00.000Z"),
853
+ score: 92,
854
+ valueExisted: true
855
+ },
856
+ {
857
+ _id: ObjectId("63595116b1fac2ee2e957f17"),
858
+ date: ISODate("2021-03-10T00:00:00.000Z"),
859
+ valueExisted: false,
860
+ score: 92
861
+ },
862
+ {
863
+ _id: ObjectId("63595116b1fac2ee2e957f18"),
864
+ date: ISODate("2021-03-11T00:00:00.000Z"),
865
+ valueExisted: false,
866
+ score: 92
867
+ },
868
+ {
869
+ _id: ObjectId("63595116b1fac2ee2e957f19"),
870
+ date: ISODate("2021-03-12T00:00:00.000Z"),
871
+ score: 85,
872
+ valueExisted: true
873
+ },
874
+ {
875
+ _id: ObjectId("63595116b1fac2ee2e957f1a"),
876
+ date: ISODate("2021-03-13T00:00:00.000Z"),
877
+ valueExisted: false,
878
+ score: 85
879
+ }
880
+ ]
0 commit comments